- Hardware & Machines
- CNC Machines
- Milling Machines
- Retrofitting Mikron WF41C: Distance coded homing success
Retrofitting Mikron WF41C: Distance coded homing success
Could this make sense?
It certainly could be added in to the homing sequence code, but bear in mind that it does need to be handled via the index-enable mechanism as index pulses themselves are typically too brief to detect in the servo thread.
But major changes to homing code would have to go in to master for testing, and probably wouldn't be released this year.
A HAL component can be working today, and can be used to test the logic.
Whether it belongs in homing or encoder I am undecided. Homing is already complicated enough to confuse most users (and developers). It feels like a variant on an absolute encoder.
Please Log in or Create an account to join the conversation.
I was thinking that it would be possible to input the absolute position to joint.N.position-fb and have that used as the position.
However, on seeing index-enable go to false, the effect is to set an internal offset such that the index position becomes HOME_OFFSET.
It would be possible to input the absolute position _after_ the index-enable has been reset, but that would cause an instant following-error.
(though on re-enabling the machine, the position would be correct)
Setting the f-error very large is no help, as the effect then would be an uncontrolled move to the HOME_OFFSET position.
So, i think that we are back to doing this in the homing code rather than in the encoder or in a HAL component.
If the system is configured with HOME_ABSOLUTE_ENCODER then the position-fb is used as actual joint position. But in that case there is no motion in search of an index.
Please Log in or Create an account to join the conversation.
The sample code earlier was using a raw_position. I think that this would actually have to be added as a HAL pin: a joint.N.raw-pos-fb which would have to be connected to a scaled-to-position version of the encoder rawcounts.
The system could attempt to just read and store position-fb at servo-thread rate. But if the axis is moving more than 0.01mm/ms (ie 10mm/s) the measured delta would be too inaccurate to trust.
Please Log in or Create an account to join the conversation.
I moved exactly in the direction you describe. I already added to following fields to the joint-ini-section and have them now available in the homing routines:
# HOME_DISTANCE_CODED enables / disables support for homing of distance coded glasscales
HOME_DISTANCE_CODED = 1
# HOME_DISTANCE_CODED_N specifies the nominal number of steps the coding marks are separated
HOME_DISTANCE_CODED_N = 1000
# HOME_DISTANCE_CODED_SP specifies the signal period of the analog signal coming from the glasscale
HOME_DISTANCE_CODED_SP = 0.02
Further I added another input pin called
joint.N.motor-pos-raw-fb
Even the Mikron at hand has rotary encoders on the servos but they are only used within the Bosch drives and not forwarded to the control.
Next step is now to add the math for distance coded homing. But after that it will probably be some time until we can test as we did not connect / test the servos controlled from LinuxCNC yet.
Best regards,
Marc
PS: @gaston48: As you already figured out the analog servo control of your Mikron would you be willing to share your PID parameters with us. This would probably help us quite a bit.
Please Log in or Create an account to join the conversation.
You can probaby skip this one, and use the presence of the other ones to be the enabling flag.# HOME_DISTANCE_CODED enables / disables support for homing of distance coded glasscales
HOME_DISTANCE_CODED = 1
That is probably easier than the equation shown.Next step is now to add the math for distance coded homing. But after that it will probably be some time until we can test as we did not connect / test the servos controlled from LinuxCNC yet.
distance = raw_position - position-fb // position-fb contains the distance travelled since second reset
if (home_latch_v > 0) {
if (distance > nominal spacing) // hit mark then delta
position = nominal spacing * (distance - floor(distance)) / delta + delta + position-fb
} else {
position = nominal spacing * (ceil(distance) - distance) / delta + position-fb
}
} else {
if (distance < nominal spacing) // hit mark then delta
position = nominal spacing * (distance - floor(distance)) / delta + delta + position-fb
} else {
position = nominal spacing * (ceil(distance) - distance) / delta + position-fb
}
}
Well, that's my first guess anyway.
Please Log in or Create an account to join the conversation.
PS: @gaston48: As you already figured out the analog servo control of your Mikron would you be willing to share your PID parameters with us. This would probably help us quite a bit.[/quote]
Hello,
My parameters, under 2.7.15 RTAI therefore under 32 bit
servo_period 500 000 ns
In hal, encoder.velocity => pid.feedback-deriv connected
switching from analog output of the TNC 355 to analog
output of the 7i77 may require a correction of the offset
Bosch amplifiers
We set a good margin to FERROR and MIN_FERROR 200 for example
We test the activation and deactivation of the bosch amplifiers, we check that
the Z brake is indeed deactivated and reactivated ...
If necessary, offset is corrected.
Then axis 0 FF1 = 0.101 axis 1 FF1 = 0.101 axis 2 (Z) = 0.121
we test with jog if real speed = speed reference
we check if axis direction +++ also involves encoder count +++
Then we go up P and D for minimum error without oscillations and noise
my final parameters:
axe 0 P = 8 I = 0 D = 0.03 FF0 = 0 FF1 = 0.101 FF2 = 0
axe 1 P = 8 I = 0 D = 0.03 FF0 = 0 FF1 = 0.101 FF2 = 0
axe 2 P = 7 I = 0 D = 0.03 FF0 = 0 FF1 = 0.121 FF2 = 0
The "spike" at reverse motion is approximately equal to that of the TNC 407
I have not yet tested FF2 to try to minimize this error
reverse "spike" with tnc 407 dia 40 mm and halscope error spike with linuxcnc
Attachments:
Please Log in or Create an account to join the conversation.
that will be tremendously helpful when in the coming weeks we will try to make the machine moving with LinuxCNC.
Best regards,
Marc
Please Log in or Create an account to join the conversation.
I'm not sure if I understand everything your code is supposed to do. However I completed the distance coded homing to my best knowledge. The new parameters in the ini-file are:
# activating distance coded homing (@andypugh I there is more than one parameter assiciated with distance coded homing I kept the explicit activation)
HOME_DISTANCE_CODED = 1
# Nominal steps between two index marks on the equally spaced index sequence
HOME_DISTANCE_CODED_N = 1000
# amount of pulses consumed by the control during one analog signal period (typically interpolation factor times 4 for quadrature)
HOME_DISTANCE_CODED_OS = 20
# width of index-pulse as provided to LinuxCNC (see comments below)
HOME_DISTANCE_CODED_PW = 2
In the C-code iteself beside exposing some more parameters within the homing environment (from the ini-file as well as the joint itself) and adding a new raw encoder position to the joint the only real additions to the code I did are the following section(see comments):
case HOME_SET_INDEX_POSITION:
if((H[joint_num].home_flags & HOME_DISTANCE_CODED) && (nr_ref_marks < 1)) {
/* Searches for the first reference mark and store its raw encoder position
in 'raw_trigger_1'. Then it resets the homing state to HOMEO_INDEX_SEARCH_START
to look for the the second homing mark */
raw_trigger_1 = joint->motor_pos_raw_fb - round(joint->pos_fb * H[joint_num].encoder_scale);
++nr_ref_marks;
H[joint_num].home_state = HOME_INDEX_SEARCH_START; //sent it back to index mark search
}else if((H[joint_num].home_flags & HOME_DISTANCE_CODED) && (nr_ref_marks < 2)){
raw_trigger_2 = joint->motor_pos_raw_fb - round(joint->pos_fb * H[joint_num].encoder_scale);
++nr_ref_marks;
// calculate and set the 'home_offset' based on raw_trigger_pos_1, raw_trigger_pos_2
int position = distance_coded_position(
raw_trigger_1,
raw_trigger_2,
H[joint_num].home_distance_coded_n,
H[joint_num].home_distance_coded_os,
H[joint_num].home_distance_coded_pw
);
H[joint_num].home_offset = (double)position / H[joint_num].encoder_scale;
}else{
/* This state is called when the encoder has been reset at
the index pulse position. It sets the current joint
position to 'home_offset', which is the location of the
index pulse in joint coordinates. */
/* set the current position to 'home_offset' */
joint->motor_offset = - H[joint_num].home_offset;
joint->pos_fb = joint->motor_pos_fb -
(joint->backlash_filt + joint->motor_offset);
joint->pos_cmd = joint->pos_fb;
joint->free_tp.curr_pos = joint->pos_fb;
if (H[joint_num].home_flags & HOME_INDEX_NO_ENCODER_RESET) {
/* Special case: encoder does not reset on index pulse.
This moves the internal position but does not affect
the motor position */
offset = H[joint_num].home_offset - joint->pos_fb;
joint->pos_cmd += offset;
joint->pos_fb += offset;
joint->free_tp.curr_pos += offset;
joint->motor_offset -= offset;
}
/* next state */
H[joint_num].home_state = HOME_FINAL_MOVE_START;
immediate_state = 1;
nr_ref_marks = 0;
break;
}
and a function to calculate the absolute position on the glasscale:
int distance_coded_position(double raw_trigger_1,
double raw_trigger_2,
int nominal_steps,
int over_sampling,
int index_pulswidth)
{
/* This function calculates the absolut position of the second trigger signal
on a distance coded glasscale (e.g. Heidenhain LS***C) as a integer number of
signal pulses after interpolation and quadrature if enabled. 'raw_trigger_1' is
the raw encoder position of the first index-mark found during homing and
'raw_trigger_2' that of the second one. 'nominal_steps' is the nominal number
of analog signals (before interpolation and quadrature) between constant space
series of index mark on the glasscale (approximately twice the distance between
two neighbouring index marks). 'over_sampling' defines how many signals LinuxCNC
receives while travling over one analog signal period i.e. the interpolation
factor times four if quadrature is enabled. 'index_pulswidth' is the width of
the index-signal after interpolation and quadrature in units of regular distance
pulses (typically the value is two). */
int Mrr = (round(raw_trigger_1) - round(raw_trigger_2)) / over_sampling;
int R = 2 * ABS(Mrr) - nominal_steps;
int P1 = ((ABS(R) - SGN(R) - 1) * nominal_steps / 2
+ (SGN(R) - SGN(Mrr)) * ABS(Mrr) / 2) * over_sampling
+ SGN(Mrr) * index_pulswidth / 2;
return P1;
}
I added to the Heidenhain fromula from @gaston48 the additional correction for the pulse-width that consistent homing is achieved independent from the homing direction. This function I could test with the data I recorded when testing the Heidenhain LS403 and the positions calculated are correct.
The homing procedure itself I can only test/debug once the machine is connected to the LinuxCNC control and we have the analog servos under control which hopefully will be in the next 1-2weeks (no guarantees).
Generally I think all my modifications are non-intrusive i.e. they don't change the behavior of LinuxCNC in any way for cases not employing distance code homing.
Happy to get critical feedback on it.... It is the first time I try to code within LinuxCNC.
Best regards,
Marc
Please Log in or Create an account to join the conversation.
This puts the distance-coding in a HAL module, which opens the way to other coding schemes that might exist.
Please Log in or Create an account to join the conversation.
not sure if I get it right. So as I understand you would create a HAL-module that gets as inputs the position counts as well as the raw-counts from the encoder. Further it would have input parameters to describe the glasscale-physics (nominal steps, index-puls_width). The glasscale would wait until the encoder was reset twice and output a kind of virtual home-switch trigger to stop the homing move. The HAL-component then could calculate the absolute position in terms of encoder counts of e.g. the second trigger point or even the current position. But then I'm missing how to set the output of the encoder to the current position that it can feed the right input into position-fb. I could not find a function in the encoder that allows a manual reset to a certain position.
The only option that I see is that the HAL-component could set the HOME_OFFSET.
Regards,
Marc
Please Log in or Create an account to join the conversation.
- Hardware & Machines
- CNC Machines
- Milling Machines
- Retrofitting Mikron WF41C: Distance coded homing success