Hi there,
I am sharing below my learnings and configuration files to setup engraving on cylindrical surfaces.
Key of the solution is a custom kinematics setup named cyl4thaxiskins.c that is somewhat similar to rot4thaxiskins.c from Martin Lederhilger 2012. Documentation of the code is done directly within the file. To use, replace the trivkins.c in the .hal with:
Code:
loadrt cyl4thaxiskins
setp cyl4thaxiskins.H1 0
I did not use the variable H1, which would be intended to define the height of the rotation axis from the machine origin (deactivate this feature by setting H1=0).
Part of the approach is to exchange Y <--> U coordinates to use 'orginial xu plane' as xy plane. This way we can run any G1, G2, G3 or even splines on any cylindrical surface.
At startup, the system behaves as default trivkins kinematics. The cross-over from flat to warped coordinates uses a cylinder radius variable. The singularity in the forward transformation forces us to restrict the mapping to radii > 1E-6. To avoid joint following errors when switching between the geometries, the radius variable shall only cross the threshold of 1E-6 at y=0. Whenever it is already bigger than 1E-6, the radius can be changed continuously without conflicts. This way, engraving can simply be done on sections with different radii in one CNC run.
The radius can alternatively be used to define the scaling of the y coordinates. Circles will then be squeezed to ellipses.
Some care has to be taken when using G92 on Y,U, or W. To position the tool at the cylinder xy center plane, the variable v is used instead of G92 Y0 (the trivkins behavior is over-written). The variable v controls the physical y-axis of the machine (no tool compensation provided thus). I suggest to use G92 on Y Axis only once, to initially set Y=0 at the cylinder xz center plane.
When using this kinematics, pos.tran.y will not be the physical y-axis anymore. It will be a virtual axis going around the circumference of a cylinder. The transformation from a -> u is u = a*radius (no discontinuities). The reverse transformation is m_a = r2d(pos->tran.y)/radius, with #define r2d(r) ((r)*180.0/PM_PI). The singularity at zero radius is lifted by a if case structure, returning to trivkins behavior for radius < 1E-6. However, prior to returning, please send first G0 Y0, then G1 W0 (this is not done automatically to avoid machine crashes).
The key code parts are, for forward transformation:
Code:
pos->a = joint[3] - to_a - rad2deg*joint[1]/joint[8];
pos->tran.y = joint[1]; //stored virtual y pos. to grap in inverse kin
and or inverse transformation:
Code:
joint[3] = to_a + rad2deg*(pos->tran.y)/(pos->w); // yaxis to angle in rad
joint[1] = pos->tran.y; // Commands on Y will rotate axis A only
Note: Cleaned kinematics file in later post, 23.04.2022. Attention, I changed the axis assignments below to make the config it more useful.