machinekit / machinekit-cnc

CNC stack split out into a separate package
Other
60 stars 37 forks source link

motion: can we kill free and teleop modes, yielding a modeless planner? #17

Open ArcEye opened 6 years ago

ArcEye commented 6 years ago

Issue by mhaberler Sat Dec 6 22:31:20 2014 Originally opened as https://github.com/machinekit/machinekit/issues/396


I am considering how to remove teleop mode from motion, and possibly free mode; the insane mode switching with all its abortive behavior is a major stumbling block driving motion from more than input source, for instance a more sane jogging architecture but also other applications

for the below it's instructive to read https://github.com/araisrobo/linuxcnc/blob/master/src/emc/motion/teleop-notes

one question I have is on forward kinematics, see https://github.com/araisrobo/linuxcnc/blob/master/src/emc/motion/teleop-notes#L61

First, note also that ALL kinematics currently in the code base yield KINEMATICS_BOTH (i.e. both forward and reverse kins available), which in effect makes teleop and coord mode identical

(1) is it actually conceivable that for ANY machine, you can NOT come up with an unambiguous forward kins? I have a hard time imagining any such scenario - isnt it that given joint positions, one can always compute the cartesian position of the end effector? (I would rather want to)

if the answer to this question is 'no', then teleop mode is a red herring and can be safely dropped (wouldnt be the first fish of this kind, size and age on the angle)

while we are on the subject of removing modes, a second question - on removing free mode; the only use for free mode I see is for homing

Right now the only type of move one can feed the coord mode planner is a cartesian pose, i.e. kins applied, all axes specified, and in homed state

Now assume what is currently coord mode had a new command which specified a move endpoint in joint positions (i.e. which joint(s) affected and how much): this would in effect be a joint move (one or several joints), BUT using the coord mode planner. IOW: no more need for the 'free mode planner', and 'free mode'.

To home with such a modeless planner, one would have to allow such joint moves if unhomed or homed, but not allow axes (coord) moves if unhomed (it would also trivially enable jogging a gantry kins: just specify both joint endpoints)

(2) what am I overlooking? (or is this whale #2 on the angle ;-?)

ArcEye commented 6 years ago

Comment by cdsteinkuehler Sat Dec 6 23:35:13 2014


I have machines that require iterative approximate solutions to the forward kins (or at least more math than I have at my disposal). It would be convenient if working with reverse-only kins was allowed and not so buggy as it is now. I can live with some restrictions on usage, but the current code is just BROKEN if you don't have KINEMATICS_BOTH. :(

ArcEye commented 6 years ago

Comment by mhaberler Sun Dec 7 10:50:55 2014


an iterative forward kins is OK; I was looking for a case of "just cant have a forward kins at reasonable cost" - can you point me to an example? I did not find any reverse-only kins in the code base, and if that use case is a rich source of bugs, it warrants consideration if it is worth supporting

I guess my point is: if we make KINEMATICS_BOTH a requirement, significant simplifications are possible, and so far I did not see a showstopper

ArcEye commented 6 years ago

Comment by cdsteinkuehler Sun Dec 7 15:36:48 2014


On 12/7/2014 2:50 AM, Michael Haberler wrote:

an iterative forward kins is OK; I was looking for a case of "just cant have a forward kins at reasonable cost" - can you point me to an example? I did not find any reverse-only kins in the code base, and if that use case is a rich source of bugs, it warrants consideration if it is worth supporting

I guess my point is: if we make KINEMATICS_BOTH a requirement, significant simplifications are possible, and so far I did not see a showstopper

The forward kinematics for the Wally 3D printer are extremely non-trivial because even with the motors at a fixed position, the elbow angle changes as the shoulder angle moves, making it beyond my math skills to find a closed form solution. I've got code for the reverse kinematics, and was working on an iterative solution for the forward kins, but IIRC nothing is in github (or certainly not in the Machinekit repo, anyway).

Charles

ArcEye commented 6 years ago

Comment by andypugh Mon Dec 8 12:54:03 2014


Wally is an interesting example. It isn't that you can't calculate world-position from joint-position trivially, it is that there are joints with unknown (or at least unmeasured) position. I was going to suggest that it might be pragmatic to simply refuse to control such systems.

There are clearly many systems where unambiguous reverse kins is impossible, the simple elbow-up / elbow-down scenario.

ArcEye commented 6 years ago

Comment by eekeller Mon Dec 8 15:00:25 2014


interesting, I would have thought that reverse kinematics would always be the problem given the multiplicity of machines such as robot arms. It does seem like the current code assumes that both forward and reverse kinematics are available, and unforseen crashes will occur if that isn't so

ArcEye commented 6 years ago

Comment by robEllenberg Mon Dec 8 16:08:54 2014


I think the major gap right now is that the current coord-mode planner doesn't have to deal with jogging, and removing the free / teleop mode planners means adding that functionality in the coord-mode planner. The current planner is designed to follow a known and fixed path, and so the majority of the planning in 1D (with some assumptions about cornering acceleration). This doesn't really work when we think about jogging. For example, imagine jogging along the world X axis, then suddenly switching to jogging along the world "Y" axis. The way it currently is implemented (at least on a trivial machine) allows the Y axis motion to start immediately.

To fit this in the current coord-mode planner, the jog commands would probably have to be small path segments. If these were queued up in the same way as path commands, you'd have to wait for the planner to empty the current queue to get to this new move. A faster response in this scheme means either a short queue (bad for path planning), or some feedback mechanism that prevents a pileup of jogging commands in the queue. Even then, you're still experiencing a delay of at least once segment. For really responsive multi-axis jogging, you can't plan it just in 1D.

Given that, here's my suggestion for dividing up motion modes:

In "goal seeking" mode, you don't care what the exact path of the machine is, just that it moves towards your particular goal, be it in world-space or joint-space. In other words, this is generalized jogging mode. This is a fundamentally different process than path-following, and switching between modes will take care (this is basically the jog-while-paused problem).

Switching from path-following to goal-seeking:

  1. Decelerate along path to rest (i.e. pause)
  2. Save current position as "restore point"
  3. PP releases motion lock
  4. GP acquires motion lock -> jog / move as needed

Switching from goal-seeking to path-following:

  1. Move to restore point (if different from current position)
  2. GP releases motion lock
  3. PP acquires motion lock -> move along path

A nice side-effect of this structure is that there's no need to have a "one true" motion planner. As long as there's a lock on actual machine motion, path planners could be saved and restored as needed, or even be disposable (i.e. running a G-code program spawns a new path planner object).

@andypugh and @cdsteinkuehler, that's a good point about the Wally 3D printer. Glancing at the design, it looks like the Wally printer has 2 solutions for a given set of motor positions. If you know the previous world position / velocity, you could choose the more likely of the two solutions (or put an encoder on one of the uncontrolled joints).

ArcEye commented 6 years ago

Comment by amitgoradia Tue Dec 9 17:34:06 2014


@Rob excellent point about the fundamental difference between path-following and jogging/motion-without-a pre-defined-endpoint.

About Wally 3D Printer, the forward kinematics are defined however there needs to be at least one more variable observed (by an encoder or using previous position knowledge and assuming continuity in the temporal space).

AFAIK, Forward kinematics are, in general, almost always computable and that too almost always trivially (given enough information regarding uncontrolled and redundant joints). We are assuming rigid body motion.

Another way to partition up the planners would be (using Rob's terminology):

  1. Path-following planner (for current coord planner)
  2. Path-following planner for current teleop planner with feed-hold and motion queue discard.
  3. Goal-seeking / Joint mode planner.

This partition would streamline the use of the kinematics module in the Path-following planner while the goal-seeking planner would always bypass the kinematics module and directly generate trajectories for the joints.

I believe the intention of the teleop mode was to enable jogging in the coordinated mode by using the kinematics module while still exhibiting the goal seeking behavior. Teleop(erated) mode would imply manually providing jogging commands just like tele-operation of manipulators.

Now, following the planner schema I am proposing, we end up in the same place as the current linuxcnc planner!! which according to me is logical. We should, however, try to simplify the implementation and the abortive behavior of the planners.

ArcEye commented 6 years ago

Comment by robEllenberg Tue Dec 9 17:49:01 2014


@amitgoradia Thanks! Do you think path-following is necessary for what the tele-op planner currently does? My understanding was that tele-op mode was basically for jogging / homing in world coordinates, which seems much more like goal-seeking than following a queue of motions. For any machine with non-trivial kinematics, you'd need goal-seeking in world space more frequently than in joint space.

ArcEye commented 6 years ago

Comment by amitgoradia Tue Dec 9 17:53:50 2014


Another issue that needs to be addressed for a full kinematics implementation is a world space command velocity and acceleration limit.

The velocity and acceleration limits should be specified in the joint space for each physical joint. The axis / task space velocity and acceleration should be limited by the kinematics and the current joint position and velocity.

Now the limiting axis velocity is different at different points in the world frame based on the current location and the kinematics. So a new concept of "Kinematic Length" can be introduced. This kinematic length will be the minimum length over which we can expect the joint velocity and acceleration limits will not be violated. (I understand that this will be hard to expect and prove around kinematic singularities).

All the path segments supplied to the path planner (The one that includes kinematics solutions), should be first be (probably recursively) broken down to the kinematics length and a max world space velocity constraint applied to them. Further a limiting velocity should be calculated based on forward velocity kinematics (given a joint space max velocity, calculate the max task space velocity around the current operating point). The minimum of the two should be used to for planning that segment.

Further some, singularity handling mechanism should also be introduced if the velocity inverse kinematics does not yield a result. This is what happens near kinematic singularities.

BTW there are 3 kinds of kinematic singularities:

  1. boundary singularity: This is encountered near the edges of the workspace where any amount of joint velocity will not let the axis attain values outside the work envelope.
  2. internal singularity: This happens when multiple joints of a serial link manipulator align in a way that motion along certain axes is not possible. (Will try to provide a reference)
  3. Representational singularity: This type of singularity is purely an artifact of the coordinate system chosen to represent the world coordinates (Will again try to find a reference)

So some singularity recognition and handling mechanism should also be put into place in case we are thinking about a re-write of the planner and kinematics modules.

my 2c

ArcEye commented 6 years ago

Comment by amitgoradia Tue Dec 9 18:05:44 2014


@Rob: My take is the the difference in the teleop v/s free planner is the kinematics module.

The free planner does not need the kinematics module and will do a 1D plan at the joint level. The teleop planner needs to take into account the kinematics module and do a 1D plan on the axis / world space level. Multiple free planners can be run simultaneously to achieve the behavior Rob is talking about. i.e., jogging multiple joints simultaneously. However, only 1 teleop planner can be executed at once because its output affects all the joints simultaneously. Running multiple teleop planners simultaneously necessarily implies summation of the current commanded velocity at the task / world level and then applying the kinematics module to the vector sum of the task command.

One more point that I wanted to clarify (which is alluded to in the joint axes branch) , is that axis limits should be applied to joints as the limiting factor in robots (that is what linuxcnc is all about right!!!) is the joint positions. Task / world space limits are derived limits based on the kinematic parameters and joint limits.

ArcEye commented 6 years ago

Comment by robEllenberg Tue Dec 9 18:28:49 2014


@amitgoradia I think I see what you're getting at in regards to the free / teleop planner. Is there an advantage to having 9 1D planners over a single free planner for all of the joints? Here's how I had imagined it: kinematics-flow

This makes it so that we don't need two completely independent planners for "free" and "teleop".

ArcEye commented 6 years ago

Comment by amitgoradia Tue Dec 9 18:42:24 2014


@Rob: If I understand correctly, what you suggest may violate workspace constraints. and the axis may not move in a straight line. All joints will move at their own rate giving rise to un-reasonable motion. Please correct me if I have not understood your scheme correctly.

A very conceivable scenario will be: The initial and final position may be outside the workpiece. But the intermediate positions may pass through the workpiece. And worst part will be you can't tell in advance if that will happen on this particular commanded move because all the joints will be moving independently. So you wont be able to predict all the task space locations that will be visited.

I feel a world axis jog should necessarily do a straight line motion in the world axis - not just a go-to end point motion by just independently jogging the joints.

@Rob: I also wanted to shout out a BIG THANK YOU for getting the look ahead feed planner done.

ArcEye commented 6 years ago

Comment by robEllenberg Tue Dec 9 19:02:02 2014


@amitgoradia That makes sense. If the goal is too far from the initial position, and the kinematics are very non-linear (like a serial-link arm or hexapod), then strange things could happen. Part of the world-space planner's job would be to generate intermediate goal points, so that the path approximates a straight line through world space. That's where your concept of kinematic length can be very useful, so that the intermediate goal is always close enough that we can assume the kinematics are locally linear.

Similarly, the joint-space planner would ensure that all joints approached their goal at that same rate. If one joint hits its velocity or acceleration limit, then the joint-space planner can simply scale back the other joints proportionally so that the goal is reach simultaneously. This is one reason to prefer a single joint-space planner over 9 independent planners.

ArcEye commented 6 years ago

Comment by amitgoradia Tue Dec 9 19:16:00 2014


If we have the teleop mode planner generating intermediate points, which would then be put into a trajectory planner at the joint level, it may give rise to a very jerky world space jog with the joints accelerating and decelerating at each endpoint. (please correct me if I am not understanding your concept clearly).

An easier way, since we already have the coord planner in place which includes the kinematics module, would be to use the coord planner with a very far axis endpoint and do a feedhold and motion queue clear on jog stop or switch hit. Kind of like doing a G38 probing move using the coord planner.

We need to clear up under what conditions the teleop planner will be allowed to be run: All joints homed? Cause only then will a forward kinematics solution be valid!! ( I am talking about general purpose kinematics not the trivial case).

BTW: As I see it I am arguing in favor of the current structure of a coord, teleop and free planner.

ArcEye commented 6 years ago

Comment by robEllenberg Tue Dec 9 21:30:44 2014


The way I was thinking is to update the joint-space goal before it actually reached the intermediate goal, so that it doesn't have to decelerate / accelerate and cause stutter as you describe. Still, as I'm thinking about it more, it may be difficult to do that well. I can see the benefits of just using the tech that's already there to do path-planning, and live with the small sacrifice in response time.

In that case, it makes sense to keep a similar superficial structure to what there is now (i.e. free mode, teleop mode, and coord mode), but maybe formalize the mode transitions so that we can easily pause and resume a trajectory.

ArcEye commented 6 years ago

Comment by mhaberler Sat Jan 3 01:01:50 2015


I cannot discern a difference between teleop and coord mode except for the conditions entering the mode, and the source & format of movement commands.

Do we really need teleop? I think it's just a roundabout way of saying "I'm listening to the UI/wheel rather than the interpreter", which has nothing to do with modes but rather input sources.

ArcEye commented 6 years ago

Comment by mhaberler Sat Jan 3 01:07:15 2015


@robEllenberg - re your diagram - do you consider the following approach possible:

There's a single locus where goals enter motion goal commands are tagged as to whether they refer to axis or joints, and which ones (null values allowed) there is always a second kinematics available (identity) a coord move selects the machine kins, and carries axis movement(s) a joint move selects the identity kins, and carries joint move(s)

IOW: everything goes through the coord mode planner; just which joints/axes are driven, and which kins is used is determined by a command attribute, not "motion mode"

under such a setup, can we drop the separate planners? such a modeless planner would be way more flexible to use I guess

ArcEye commented 6 years ago

Comment by mhaberler Tue Feb 24 23:03:35 2015


fyi - the 'loadable tp' branch and underlying vtable support has been merged

ArcEye commented 6 years ago

Comment by jpmoniz Fri Apr 17 14:46:44 2015


Firstly please correct me at any point when I am wrong.

Few thoughts on teleop after doing some investigating on why incremental jogging in telleop is not allowed.

Why can't tellop moves be ran through the current tp? As I under stand in tellop moves are velocity vectors that bypass the Cartesian planner.

Looking at jogs in free mode we just give an endpoint past the joints limits, and then allow it to move until we say stop. What if the same approach was taken with teleop moves but using the coord planner? Pass the planner a target for the Cartesian axis requested to jog in, past its limit, and let it move until we say stop. This should be no different the executing an MDI command and then pressing stop halfway through execution. What am I missing? Would this not help kill the need for teleop, leaving two modes coordinated and free?

ArcEye commented 6 years ago

Comment by mhaberler Fri Apr 17 23:01:12 2015


I did not find a good answer why these separate "axis planners" exist either I think the primary stumbling block is the abortive mode switching (entering/leaving coord mode flushes the motion queue)

ArcEye commented 6 years ago

Comment by jpmoniz Sat Apr 18 00:35:07 2015


@mhaberler @robEllenberg Ok so that was my second thought that I held back. What if you had a que for each mode that may exist. Dependent on the mode is what motion listened to. I'm thinking for jog while paused and other typical situations if there were dedicated que by mode then jogging while paused or reversing the motion que would be attainable would it not? Thinking this may be a good use of ring buffers here. Sorry i'm just trying to understand the issues while learning the innards.

If task is the master, telling the interp what to do, and telling motion what to listen to, does my logic hold up?

ArcEye commented 6 years ago

Comment by mhaberler Sat Apr 18 03:32:06 2015


yes, I think multiple queues and switching them could work that way ('jog while pause' kind of does this although there is no upper-level api to the secondary queue, it's just fed by vectors derived from pin values)

that would pave the way towards the "MDI while paused" - when paused, connect a different interp and a different queue, MDI around, then switch back at some safe point (when the new queue is empty again and the machine returned to the position where the switch happened)

I'm not sure the "multiple queue" idea should be tied into mode switching though, I see that rather a different concept from mode switching; my hope was life would be easier with a modeless planner and motion commands which carry the "mode" on a per-command basis, not a global state switch (which kins to use, and if axes or joints are to move; in the case of joints - which ones)

ArcEye commented 6 years ago

Comment by jpmoniz Sat Apr 18 04:19:45 2015


@mhaberler In a way I think were thinking the same thing. The only obstacle I was thinking of was the situation where you have the "Interp list" full of commands from "automatic program execution" what do you do when you want to pause and switch to jogging? My thought was to keep those commands in the list and just switch to a different list to get direction from. When done return to the list that you want to listen to and continue.

Dont get me wrong I like the idea of having a position command with status flags to indicate who should listen and why. I just dont know the code enough to suggest a workable solution.

JP