LinuxCNC S-Curve Accelerations

More
14 Apr 2021 09:58 #205869 by rodw
Replied by rodw on topic LinuxCNC S-Curve Accelerations
I think they are assumed to be constant as the ini file is meant to describe your unchanging hardware. I nearly mentioned in my last post you could experiment changing it on the fly with sim_pin but its a user space component
linuxcnc.org/docs/devel/html/man/man1/sim_pin.1.html
Its actually very handy for tuning pid loops etc.

When I looked at my config, the ini accel values are sent to the mesa stepgens so I'm not sure how that maps to motion.

Please Log in or Create an account to join the conversation.

More
14 Apr 2021 14:24 #205898 by arvidb
The hostmot2 accel limit seems to be just another layer of "motion filtering"? The position (or velocity) values that come from LinuxCNC should be acceleration limited already, so you could probably disable the hm2 acc limit (set it to zero)?

I've been looking at the code some more and the EMCMOT_SET_JOINT_ACC_LIMIT command seems to be issued in only two places: inihal.cc and inijoint.cc. The latter reads out the settings from the INI file and the former creates hal pins: ini.N.max_acceleration. These pins are monitored for changes and on change the new value is propagated to joint->acc_limit (in emc/motion/command.c). So it seems it's actuallly possible to change the acceleration limits on the fly.

BTW, there's a bug in emc/motion/control.c where the code that's supposed to adjust the joint velocity limit to net_feed_scale is unreachable. The whole thing is in a switch (emcmotStatus->motion_state) statement under case EMCMOT_MOTION_FREE. Then at line 1199 the if statement checks for (emcmotStatus->motion_state != EMCMOT_MOTION_FREE) ...

Also there's a weird if statement just above it that lowers joint->acc_limit if it's over the limit set in emcmotStatus, i.e. the acceleration limit for Trajectory moves (set with emcTrajSetAcceleration()). This is probably a bug, too?

Please Log in or Create an account to join the conversation.

More
14 Apr 2021 15:53 #205912 by arvidb
Another question: Why is cubic interpolation applied to TELEOP motion (axis jogs)?

Please Log in or Create an account to join the conversation.

More
15 Apr 2021 10:01 #205989 by rmu
Replied by rmu on topic LinuxCNC S-Curve Accelerations

Another question: Why is cubic interpolation applied to TELEOP motion (axis jogs)?


what exactly are you referring to? IIRC, everything goes through cubic interpolation, I suppose to avoid discontinuities in the velocities.

Please Log in or Create an account to join the conversation.

More
15 Apr 2021 10:08 #205991 by rmu
Replied by rmu on topic LinuxCNC S-Curve Accelerations

Also there's a weird if statement just above it that lowers joint->acc_limit if it's over the limit set in emcmotStatus, i.e. the acceleration limit for Trajectory moves (set with emcTrajSetAcceleration()). This is probably a bug, too?


look at git blame (e.g. github.com/LinuxCNC/linuxcnc/blame/maste...tion/control.c#L1196) for a hint.

Please Log in or Create an account to join the conversation.

More
15 Apr 2021 12:48 #206001 by arvidb
The comment for that commit says "honor [TRAJ] ACCELERATION settings in free mode planner" - but that's a bug, right? Why would one want that? As a user, if I set MAX_ACCELERATION under [JOINT_N], I expect that acceleration to be used for joint jogs. Not the DEFAULT_LINEAR_ACCELERATION set for cartesian motion under [TRAJ]?

The commit was made in 2008 while axis and joints were not differentiated. Maybe it just happened to be left behind in that split?

(Regardless, the code is still buggy since it modifies joint->acc_limit (e.g. even if DEFAULT_LINEAR_ACCELERATION is raised again the value is not restored). Something like local_acc_limit = fmin(joint->acc_limit, emcmotStatus->acc); would probably have been more suitable?)

Please Log in or Create an account to join the conversation.

More
15 Apr 2021 13:13 #206003 by arvidb

Another question: Why is cubic interpolation applied to TELEOP motion (axis jogs)?


what exactly are you referring to? IIRC, everything goes through cubic interpolation, I suppose to avoid discontinuities in the velocities.


Sorry, I should have elaborated much more.

When looking at the code and comments in emc/motion/control.c it looks like, sometime in the past, the trajectory planner was run at the "traj rate". (This might be the CYCLE_TIME set under TASK? - anyway, slower than the servo rate. See e.g. control.c:1578 or search the code for "traj rate".) And the cubic interpolator was used to smooth out the motion between the coarse positions returned from the trajectory planner at this slower rate.

Today, trajectory planning and kinematics are run at the servo rate (although there are several FIXME comments in the code saying these should be changed to run at the traj rate). I assumed cubic interpolation helped smooth out direction transitions which could still be useful for coordinated movement.

Joint jogs does not use the cubic interpolator, but axis jogs does, which seems strange to me since the axis jog planner (simple_tp) should produce smooth, acceleration-limited motion already. simple_tp also supplies (or could easily supply) acceleration and velocity setpoints so getting those are also no reasons for using the interpolator.

One thing I noted is that there are several places where teleop_tp->curr_vel is forcibly set to zero instead of letting the planner slow down with limited acceleration. I guess using the interpolator at least partly mitigates those bugs. (This is a perfect example of why data encapsulation is important: "outside" code should never have been allowed to modify simple_tp's curr_vel directly.)

The background to all this is of course that I'm trying to figure out how to fit my jerk-limited jog planner into the code, so I need to understand not only how things work but also the rationale behind it.

Please Log in or Create an account to join the conversation.

More
15 Apr 2021 16:58 #206021 by rmu
Replied by rmu on topic LinuxCNC S-Curve Accelerations


When looking at the code and comments in emc/motion/control.c it looks like, sometime in the past, the trajectory planner was run at the "traj rate". (This might be the CYCLE_TIME set under TASK? - anyway, slower than the servo rate. See e.g. control.c:1578 or search the code for "traj rate".) And the cubic interpolator was used to smooth out the motion between the coarse positions returned from the trajectory planner at this slower rate.


AFAIU, the trajectory planner could be run at an arbitrary rate, even in the non-realtime-domain, as long as it supplies segments fast enough. "Execution" of the segments happens in the servo thread. Segments are either lines or circular arcs. I'm not talking about the simple_tp, and spindle synced motion also is a somewhat separate story.

I agree that the code is bowl of spaghetti, pluck a noodle and everything moves. Cleaning that up would be a major undertaking and it is unlikely any major change could ever be merged.

Please Log in or Create an account to join the conversation.

More
16 Apr 2021 14:16 - 16 Apr 2021 14:29 #206107 by arvidb
Let's use the terminology from the source to avoid confusion:

free_tp: joint jog planner, instance of simple_tp. Joint coordinate space.
teleop_tp: axis jog planner, instance of simple_tp. Cartesian space.
coord_tp: coordinated move planner, instance of TP_STRUCT. Cartesian space.

AFAIU, the trajectory planner could be run at an arbitrary rate, even in the non-realtime-domain, as long as it supplies segments fast enough. "Execution" of the segments happens in the servo thread. Segments are either lines or circular arcs. I'm not talking about the simple_tp, and spindle synced motion also is a somewhat separate story.


We are at a lower level than line or arc segments here, in emc/motion/control.c. Look at the code starting at line 1309, case EMCMOT_MOTION_COORD. If the cubic interpolator needs a new point, tpRunCycle() and tpGetPos() are run on coord_tp to get a new cartesian position command (carte_pos_cmd). This is run through inverse kinematics. The results are assigned to the respective joint's coarse_pos member, and are also fed into the cubic interpolator.

Then as a final step the actual "fine" joint position (joint->pos_cmd) as well as velocity and acceleration commands are gotten from the cubic interpolator.

I haven't looked into the cubic interpolator, but maybe this significantly reduces the cpu load by running the inverse kinematics much more seldom than otherwise needed? It looks like it isn't run at the servo rate after all (unless the interpolator requests a new point every cycle).

After some more code reading: The "traj period" is a parameter to motmod.so. It is set to the servo period if not specified .

Ok, so this explains why the output from teleop_tp is run through the interpolator: it allows to run inverse kinematics at a lower rate than the servo thread, during axis jogs, by specifying traj_period_nsec to be larger than servo_period_nsec.

Then a new question arises: is this feature still meaningful today? The only reason to use it that I can see is if inverse kinematics is too slow to fit in a servo period, and then you'd get a realtime delay in the servo thread each time the traj period is reached anyway.

Edit: Why not move the cubic interpolation to the kinematics module instead? Then it could be completely skipped on trivial machines. Machines with difficult kinematics could apply it if necessary, internally computing fewer "true" waypoints than requested at the servo thread rate and interpolating the rest.
Last edit: 16 Apr 2021 14:29 by arvidb.

Please Log in or Create an account to join the conversation.

More
16 Apr 2021 23:06 #206143 by andypugh

Then a new question arises: is this feature still meaningful today?


I would guess not. But how would you know? We can change the code and see if anyone sues, I suppose.


[quote[ Why not move the cubic interpolation to the kinematics module instead? [/quote]I don't think that _in_ the kins is the way to go. But in that area makes sense.

This ties in to something that I keep meaning to try..
Kins is maths. If we calculate kins at "then" "now" and "next" then we know joint velocity and joint accel. Nearly as good is "then-1", "then", "no", ie a 2-deep buffer. In either case we can use kins as numerical differentiation to stay within Joint velocity and accel limits.

Please Log in or Create an account to join the conversation.

Time to create page: 0.180 seconds
Powered by Kunena Forum