• Tags
  • Documentation
  • Order
  • Register
  • Login
Duet3D Logo Duet3D
  • Tags
  • Documentation
  • Order
  • Register
  • Login

Inverted Delta kinematics

Scheduled Pinned Locked Moved
Firmware developers
2
25
826
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • undefined
    benjamin.forest
    last edited by 16 Nov 2020, 13:10

    Hi,

    I'm trying to implement a Linear Delta Kinematics, where the bed plate is moving instead of the printing head. The only difference is that to augment Z, you actually lower the bed so the Z axis is inverted.

    I did try to create a linear kinematics just inverting Z in CartesianToMotorSteps and MotorStepToCartesian, but I have really strange motion as a result.

    What may I be missing ?

    Pure Z motions does not seem to be affected at all by my changes (they are still moving in the wrong direction), and XYZ Motion have a problem too, they are jerky.

    Is there some kind of documentation about motion control in reprapfirmware, or information about the correct way to debug motion problems ? I'm struggling to find some starting point ...

    All the best,

    undefined 1 Reply Last reply 16 Nov 2020, 14:48 Reply Quote 0
    • undefined
      benjamin.forest
      last edited by 16 Nov 2020, 14:39

      [edit] : inverting moveArg in DoStraightMove function (Gcodes.cpp) for Z axis gives more or less the result I want, but this is not a satisfying way of getting things to work ...

      1 Reply Last reply Reply Quote 0
      • undefined
        JoergS5 @benjamin.forest
        last edited by JoergS5 16 Nov 2020, 14:48

        I delete this post, I first misunderstood the question and the answer didn't fit.

        1 Reply Last reply Reply Quote 0
        • undefined
          benjamin.forest
          last edited by 16 Nov 2020, 15:02

          Thanks a lot for you answer, I think I haven't explained myself properly.
          When I speak of Z axis, I'm speaking of the Z axis of the Tool coordinate system, not the Z_AXIS actuator / motor. It is a little confusing, because Z_AXIS in ReprapFirmware can sometimes refer to Actuator, and sometimes refer to Z coordinate.

          So to present things differently :

          • I have a normal LineAr Delta. Only my head is fix, and my bedplate is moving.
          • I want that normal G1 X Y Z => X, Y, Z movements, realworld makes the bed plate to go down. That is, a normal G1 Z5 command makes the bed plate move down 5mm.

          So my idea was to create a Kinematics, derived from Linear Delta, where the Z coordinate is inverted. That should lead to the desired behaviour.

          • Unluckyly for me, I didn't manage to have expected results just by modifing a LinearDelta Kinematics.
          • When changing The Z corrdinate a the top level I found in source, ie in DoStraightMove function, I manage to have the expected behavior. But I must have missed something, since I shouldn't have to modify this function to get a new model working.

          So I am wondering what I could be missing in code ?

          All the best,

          undefined 1 Reply Last reply 16 Nov 2020, 15:17 Reply Quote 0
          • undefined
            JoergS5 @benjamin.forest
            last edited by JoergS5 16 Nov 2020, 15:17

            @benjamin-forest I doubt I understood. The bedplate is connected like the hotend is connected at a normal delta, but the arms coming from the bottom?

            In my understanding you want the delta turned 180 degree top down and bed and hotend exchanged? This should work without any modification imho. Because there no difference of a nozzle to print on the bed and the bed moving to touch the nozzle and for the kinematics it's irrelevant in which direction it prints.

            G1 Z5 would means the nozzle shall be 5 mm more away from the bed, and this is the case in your example, bed moving down.

            If my understanding is still wrong, then sorry...

            1 Reply Last reply Reply Quote 0
            • undefined
              benjamin.forest
              last edited by 16 Nov 2020, 15:23

              Thanks, My fault. The Printer is not inverted. You can see it in action here : https://youtu.be/gORqC7tfNXI?t=22 . The bed is at the place of the hotend and moving, the hotend is fixed, above the bed.

              undefined 1 Reply Last reply 16 Nov 2020, 15:41 Reply Quote 1
              • undefined
                JoergS5 @benjamin.forest
                last edited by 16 Nov 2020, 15:41

                @benjamin-forest I suddenly want an espresso, I don't know why 😉

                Now I understand you. I would try it the same like you did. Please tell how you changed the code in detail (which lines from and to).

                1 Reply Last reply Reply Quote 0
                • undefined
                  benjamin.forest
                  last edited by benjamin.forest 16 Nov 2020, 15:56

                  Great !

                  More or less working version (unsatisfying) :

                  This is not viable, because one cannot change machine type anymore after this modification.

                  File RepRapFirmware/src/GCodes/GCodes.cpp:1836~1860 :
                  Code added :

                  if(axis == Z_AXIS)
                  {
                  moveArg = -moveArg;
                  }

                  Some context :

                  else if (gb.MachineState().axesRelative)
                  {
                  if(axis == Z_AXIS)
                  {
                  moveArg = -moveArg;
                  }
                  currentUserPosition[axis] += moveArg * (1.0 - moveFractionToSkip);
                  }
                  else if (gb.MachineState().g53Active)
                  {
                  currentUserPosition[axis] = moveArg + GetCurrentToolOffset(axis); // g53 ignores tool offsets as well as workplace coordinates
                  }
                  else if (gb.MachineState().runningSystemMacro)
                  {
                  currentUserPosition[axis] = moveArg; // don't apply workplace offsets to commands in system macros
                  }
                  else
                  {
                  if(axis == Z_AXIS)
                  {
                  moveArg = -moveArg;
                  }
                  currentUserPosition[axis] = moveArg + GetWorkplaceOffset(axis);
                  }
                  }

                  Not working version:

                  in a new InvertedLinearDelta class, derived from LinearDeltaKinematics :

                  bool InvertedDeltaKinematics::CartesianToMotorSteps(const float machinePos[], const float stepsPerMm[], size_t numVisibleAxes, size_t numTotalAxes, int32_t motorPos[], bool isCoordinated) const noexcept
                  {
                  float invertedMachinePos[MaxAxes];
                  for (size_t axis = 0; axis < numVisibleAxes; ++axis)
                  {
                  invertedMachinePos[axis] = machinePos[axis];
                  }
                  invertedMachinePos[Z_AXIS] = -machinePos[Z_AXIS];
                  bool r = LinearDeltaKinematics::CartesianToMotorSteps(invertedMachinePos, stepsPerMm, numVisibleAxes, numTotalAxes, motorPos, isCoordinated);
                  // if (reprap.Debug(moduleMove))
                  // {
                  // debugPrintf("CartesianToMotorSteps :");
                  // for (size_t i = 0; i < numVisibleAxes; ++i)
                  // {
                  // debugPrintf(" %.2f / %d", invertedMachinePos[i], motorPos[i]);
                  // }
                  // debugPrintf("\n");
                  // }
                  return r;
                  }
                  void InvertedDeltaKinematics::MotorStepsToCartesian(const int32_t motorPos[], const float stepsPerMm[], size_t numVisibleAxes, size_t numTotalAxes, float machinePos[]) const noexcept
                  {
                  LinearDeltaKinematics::MotorStepsToCartesian(motorPos, stepsPerMm, numVisibleAxes, numTotalAxes, machinePos);
                  machinePos[Z_AXIS] = -machinePos[Z_AXIS];
                  if (reprap.Debug(moduleMove))
                  {
                  debugPrintf("MotorStepsToCartesian :");
                  for (size_t i = 0; i < numVisibleAxes; ++i)
                  {
                  debugPrintf(" %.2f / %d", machinePos[i], motorPos[i]);
                  }
                  debugPrintf("\n");
                  }
                  }

                  Note : in both cases, some tweaks with limits had to be made. I don't put them here because I think they are out of scope.

                  undefined 1 Reply Last reply 16 Nov 2020, 16:05 Reply Quote 0
                  • undefined
                    JoergS5 @benjamin.forest
                    last edited by 16 Nov 2020, 16:05

                    @benjamin-forest said in Inverted Delta kinematics:

                    invertedMachinePos[Z_AXIS] = -machinePos[Z_AXIS]; bool r = LinearDeltaKinematics::CartesianToMotorSteps(machinePos, stepsPerMm, numVisibleAxes, numTotalAxes, motorPos, isCoordinated); // if (reprap.Debug(moduleMove))

                    in this lines is missing to set machinePos[z] to the new value.
                    You calculated inverted..., but don't use it.
                    machinePos[Z_AXIS] = - machinePos[Z_AXIS];
                    before calling the method.

                    1 Reply Last reply Reply Quote 0
                    • undefined
                      benjamin.forest
                      last edited by benjamin.forest 16 Nov 2020, 16:07

                      Yes sorry I actually did, it's an error in modified code I sent. I modified it accordingly. I'm in the middle of testing, so my code evolves. invertedMachinePos is needed because machinePos is const

                      undefined 1 Reply Last reply 16 Nov 2020, 16:09 Reply Quote 0
                      • undefined
                        JoergS5 @benjamin.forest
                        last edited by 16 Nov 2020, 16:09

                        @benjamin-forest I would have tried it similar like you did. To solve, calculation of some values and verify the results are necessary imho.

                        I would change kinematics, not the Gode file.

                        1 Reply Last reply Reply Quote 0
                        • undefined
                          benjamin.forest
                          last edited by benjamin.forest 16 Nov 2020, 16:14

                          Agreed. But there seems to be a trick in segmentation that uses Z value without passing by kinematics, maybe to gain some time ? Since Z is just a simple constant translation on all axes ?

                          For example file DDA.cpp and DDARing.cpp are still quite obscure to me and use move buffer. Specifically InitStandardMove seems suspect to me :), but I can't exaplin really why at the moment.

                          undefined 1 Reply Last reply 16 Nov 2020, 16:17 Reply Quote 0
                          • undefined
                            JoergS5 @benjamin.forest
                            last edited by 16 Nov 2020, 16:17

                            @benjamin-forest segmentation with trick should be with interpolations, but this should work when you just invert values. I know no other tricks, but i did not analyze all delta code.

                            1 Reply Last reply Reply Quote 0
                            • undefined
                              benjamin.forest
                              last edited by 16 Nov 2020, 16:19

                              bool DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params) noexcept Does seem to intervene as well, but I don't know how or when ...

                              undefined 1 Reply Last reply 16 Nov 2020, 16:22 Reply Quote 0
                              • undefined
                                JoergS5 @benjamin.forest
                                last edited by 16 Nov 2020, 16:22

                                @benjamin-forest you're right, eg
                                // Calculate how many steps we need to move up before reversing
                                seems to depend on direction. There may be other places.

                                1 Reply Last reply Reply Quote 0
                                • undefined
                                  benjamin.forest
                                  last edited by 16 Nov 2020, 16:23

                                  Yes, but I didn't found the way direction is actually calculated

                                  undefined 1 Reply Last reply 16 Nov 2020, 16:25 Reply Quote 0
                                  • undefined
                                    JoergS5 @benjamin.forest
                                    last edited by JoergS5 16 Nov 2020, 16:25

                                    @benjamin-forest I fear I cannot help you much, after I understood your problem. But maybe someone other can help you now, knowing the information from our discussion.

                                    If I have an idea, I'll tell you. Until then: good luck!!

                                    Best would be to have a configuration parameter for linear Delta for your case, handling the algorithm accordingly.

                                    1 Reply Last reply Reply Quote 0
                                    • undefined
                                      benjamin.forest
                                      last edited by 16 Nov 2020, 16:27

                                      Thank you very much for taking the time to understand my problem, it's always a good thing to explain things, and helps my self understanding of what I've done !

                                      All the best,
                                      and until my next post 😉

                                      undefined 2 Replies Last reply 16 Nov 2020, 16:28 Reply Quote 0
                                      • undefined
                                        JoergS5 @benjamin.forest
                                        last edited by 16 Nov 2020, 16:28

                                        @benjamin-forest good luck, see you!

                                        1 Reply Last reply Reply Quote 0
                                        • undefined
                                          JoergS5 @benjamin.forest
                                          last edited by 16 Nov 2020, 21:46

                                          @benjamin-forest I had a new idea:

                                          if you reverse the three steppers (M569 P0 S1 => S0, and S0 to S1), it should print like expected, but probably mirrored in xy direction.

                                          The inversion of xy could be solved by changing the stepper order probably, like discussed in
                                          https://reprap.org/forum/read.php?178,636057#:~:text=The mirrored printing normally means,Z tower is back centre.

                                          1 Reply Last reply Reply Quote 0
                                          10 out of 25
                                          • First post
                                            10/25
                                            Last post
                                          Unless otherwise noted, all forum content is licensed under CC-BY-SA