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

    Inverted Delta kinematics

    Scheduled Pinned Locked Moved
    Firmware developers
    2
    25
    874
    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.
    • benjamin.forestundefined
      benjamin.forest
      last edited by

      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.

      JoergS5undefined 1 Reply Last reply Reply Quote 1
      • JoergS5undefined
        JoergS5 @benjamin.forest
        last edited by

        @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
        • benjamin.forestundefined
          benjamin.forest
          last edited by benjamin.forest

          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.

          JoergS5undefined 1 Reply Last reply Reply Quote 0
          • JoergS5undefined
            JoergS5 @benjamin.forest
            last edited by

            @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
            • benjamin.forestundefined
              benjamin.forest
              last edited by benjamin.forest

              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

              JoergS5undefined 1 Reply Last reply Reply Quote 0
              • JoergS5undefined
                JoergS5 @benjamin.forest
                last edited by

                @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
                • benjamin.forestundefined
                  benjamin.forest
                  last edited by benjamin.forest

                  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.

                  JoergS5undefined 1 Reply Last reply Reply Quote 0
                  • JoergS5undefined
                    JoergS5 @benjamin.forest
                    last edited by

                    @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
                    • benjamin.forestundefined
                      benjamin.forest
                      last edited by

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

                      JoergS5undefined 1 Reply Last reply Reply Quote 0
                      • JoergS5undefined
                        JoergS5 @benjamin.forest
                        last edited by

                        @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
                        • benjamin.forestundefined
                          benjamin.forest
                          last edited by

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

                          JoergS5undefined 1 Reply Last reply Reply Quote 0
                          • JoergS5undefined
                            JoergS5 @benjamin.forest
                            last edited by JoergS5

                            @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
                            • benjamin.forestundefined
                              benjamin.forest
                              last edited by

                              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 😉

                              JoergS5undefined 2 Replies Last reply Reply Quote 0
                              • JoergS5undefined
                                JoergS5 @benjamin.forest
                                last edited by

                                @benjamin-forest good luck, see you!

                                1 Reply Last reply Reply Quote 0
                                • JoergS5undefined
                                  JoergS5 @benjamin.forest
                                  last edited by

                                  @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
                                  • benjamin.forestundefined
                                    benjamin.forest
                                    last edited by

                                    Thanks, that's a good Idea. I made this by error when I started trying. The problem is that if it works well for Z, when moving along X/Y the model is no longer valid, since motors are moving in the wrong direction. This lead to the motion being parabolic and is not usable ... Unless maybe I change my model accordingly ? I'll investigate if no other solution is possible.

                                    JoergS5undefined 1 Reply Last reply Reply Quote 0
                                    • JoergS5undefined
                                      JoergS5 @benjamin.forest
                                      last edited by

                                      @benjamin-forest if you find the mathematic formulae, it could be better to add a new kinematic, because the delta has several code in the firmware, so to overlook one is a big probability. If you install a new kinematic, there is no such danger and you have full control over the movement. I would not inherit from lineardelta, but from kinematic then.
                                      You could start with the delta code using a new kinematic, to be sure there is no specific code in Move etc.

                                      When I developed the robotic kinematic, I installed the forward and inverse kinematic in windows with mingw and calculated the cartesian coordinate from iterated stepper positions and then back inverse, then comparing, with millions of iterations. This could be a method for you too to validate the code.

                                      1 Reply Last reply Reply Quote 0
                                      • benjamin.forestundefined
                                        benjamin.forest
                                        last edited by

                                        Sure, I'll be thinking about it. I remember you were working on some test as well, did you publish something about it ?

                                        All the best,

                                        JoergS5undefined 1 Reply Last reply Reply Quote 0
                                        • JoergS5undefined
                                          JoergS5 @benjamin.forest
                                          last edited by JoergS5

                                          @benjamin-forest no, and the code is different for you, you would have not much value.

                                          It's simply setting the parameters, iterating over them with different values and calling forward and reverse kinematics, then adding up the statistics.

                                          I iterated the arm lengths, the different working modes and the stepper angles. In your case I would start iterating only over the stepper positions.

                                          I created a class for me and took only the forward and inverse kinematics methods into it, so I don't need to solve all the other references. The kinematics methods are isolated very well.

                                          1 Reply Last reply Reply Quote 0
                                          • benjamin.forestundefined
                                            benjamin.forest
                                            last edited by

                                            Thanks, I'll think about it.

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