motion: wheeljogging *.jog-accel-fraction hal pins

new motion hal pins:
    axis.L.jog-accel-fraction
    joint.N.jog-accel-fraction

Hal pins specify reduced acceleration for wheel jogging to reduce
impulsive motion when jog count changes occur at low frequency.
The pins specify a fraction (between 0 and 1) of the corresponding
ini setting for [*]MAX_ACCELERATION.  Values less than zero or
more than 1 are ignored.

When jog-counts are increased/decreased slowly, the use of full
acceleration can cause disconcerting motion or shaking on machines
with high acceleration capabilities.  This feature may be used
with or without auxiliary lowpass filtering of the *.jog-counts
inputs.

Note: Lowpass filtering of jog-counts smooths motion when
jog-counts changes are sustained but is less effective for single
event or low frequency count changes because the leading/trailing
accel occurs at the ini setting for max_acceleration.
This commit is contained in:
Dewey Garrett 2017-11-06 16:57:57 -07:00
parent c8f6b32b97
commit d69b15cfe1
5 changed files with 50 additions and 5 deletions

View file

@ -40,6 +40,11 @@ When TRUE (and in manual mode), any change to "jog-counts" will result in motion
\fBaxis.\fIL\fB.jog-scale\fR IN FLOAT \fBaxis.\fIL\fB.jog-scale\fR IN FLOAT
Sets the distance moved for each count on "jog-counts", in machine units. Sets the distance moved for each count on "jog-counts", in machine units.
.TP
\fBaxis.\fIL\fB.jog-accel-fraction\fR IN FLOAT
Sets acceleration for wheel jogging to a fraction of the ini max_acceleration for
the axis. Values greater than 1 or less than zero are ignored.
.TP .TP
\fBaxis.\fIL\fB.jog-vel-mode\fR IN BIT \fBaxis.\fIL\fB.jog-vel-mode\fR IN BIT
When FALSE (the default), the jogwheel operates in position mode. The axis will move exactly jog-scale units for each count, regardless of how long that might take. When TRUE, the wheel operates in velocity mode - motion stops when the wheel stops, even if that means the commanded motion is not completed. When FALSE (the default), the jogwheel operates in position mode. The axis will move exactly jog-scale units for each count, regardless of how long that might take. When TRUE, the wheel operates in velocity mode - motion stops when the wheel stops, even if that means the commanded motion is not completed.
@ -109,6 +114,11 @@ When TRUE (and in manual mode), any change to "jog-counts" will result in motion
\fBjoint.\fIN\fB.jog-scale\fR IN FLOAT \fBjoint.\fIN\fB.jog-scale\fR IN FLOAT
Sets the distance moved for each count on "jog-counts", in machine units. Sets the distance moved for each count on "jog-counts", in machine units.
.TP
\fBjoint.\fIN\fB.jog-accel-fraction\fR IN FLOAT
Sets acceleration for wheel jogging to a fraction of the ini max_acceleration for
the joint. Values greater than 1 or less than zero are ignored.
.TP .TP
\fBjoint.\fIN\fB.jog-vel-mode\fR IN BIT \fBjoint.\fIN\fB.jog-vel-mode\fR IN BIT
When FALSE (the default), the jogwheel operates in position mode. The joint will move exactly jog-scale units for each count, regardless of how long that might take. When TRUE, the wheel operates in velocity mode - motion stops when the wheel stops, even if that means the commanded motion is not completed. When FALSE (the default), the jogwheel operates in position mode. The joint will move exactly jog-scale units for each count, regardless of how long that might take. When TRUE, the wheel operates in velocity mode - motion stops when the wheel stops, even if that means the commanded motion is not completed.

View file

@ -1045,6 +1045,15 @@ with a minimal number of ini file settings.
Commits to unreleased branches may make changes that affect testers Commits to unreleased branches may make changes that affect testers
and early-adopters of the unreleased software. and early-adopters of the unreleased software.
=== Motion pins
New pins (see the motion man page for more info):
---
axis.L.jog-accel-fraction
joint.N.jog-accel-fraction
---
=== Hal pins === Hal pins
Name changes: Name changes:

View file

@ -855,6 +855,7 @@ static void handle_jjogwheels(void)
static int first_pass = 1; /* used to set initial conditions */ static int first_pass = 1; /* used to set initial conditions */
for (joint_num = 0; joint_num < emcmotConfig->numJoints; joint_num++) { for (joint_num = 0; joint_num < emcmotConfig->numJoints; joint_num++) {
double jaccel_limit;
/* point to joint data */ /* point to joint data */
joint_data = &(emcmot_hal_data->joint[joint_num]); joint_data = &(emcmot_hal_data->joint[joint_num]);
joint = &joints[joint_num]; joint = &joints[joint_num];
@ -863,6 +864,13 @@ static void handle_jjogwheels(void)
continue; continue;
} }
// disallow accel bogus fractions
if ( (*(joint_data->jjog_accel_fraction) > 1)
|| (*(joint_data->jjog_accel_fraction) < 0) ) {
jaccel_limit = joint->acc_limit;
} else {
jaccel_limit = (*(joint_data->jjog_accel_fraction)) * joint->acc_limit;
}
/* get counts from jogwheel */ /* get counts from jogwheel */
new_jjog_counts = *(joint_data->jjog_counts); new_jjog_counts = *(joint_data->jjog_counts);
@ -951,7 +959,7 @@ static void handle_jjogwheels(void)
if ( *(joint_data->jjog_vel_mode) ) { if ( *(joint_data->jjog_vel_mode) ) {
double v = joint->vel_limit * emcmotStatus->net_feed_scale; double v = joint->vel_limit * emcmotStatus->net_feed_scale;
/* compute stopping distance at max speed */ /* compute stopping distance at max speed */
stop_dist = v * v / ( 2 * joint->acc_limit); stop_dist = v * v / ( 2 * jaccel_limit);
/* if commanded position leads the actual position by more /* if commanded position leads the actual position by more
than stopping distance, discard excess command */ than stopping distance, discard excess command */
if ( pos > joint->pos_cmd + stop_dist ) { if ( pos > joint->pos_cmd + stop_dist ) {
@ -963,7 +971,7 @@ static void handle_jjogwheels(void)
/* set target position and use full velocity and accel */ /* set target position and use full velocity and accel */
joint->free_tp.pos_cmd = pos; joint->free_tp.pos_cmd = pos;
joint->free_tp.max_vel = joint->vel_limit; joint->free_tp.max_vel = joint->vel_limit;
joint->free_tp.max_acc = joint->acc_limit; joint->free_tp.max_acc = jaccel_limit;
/* lock out other jog sources */ /* lock out other jog sources */
joint->wheel_jjog_active = 1; joint->wheel_jjog_active = 1;
/* and let it go */ /* and let it go */
@ -993,8 +1001,18 @@ static void handle_ajogwheels(void)
if ( emcmotStatus->on_soft_limit ) { return; } if ( emcmotStatus->on_soft_limit ) { return; }
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) { for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
double aaccel_limit;
axis = &axes[axis_num]; axis = &axes[axis_num];
axis_data = &(emcmot_hal_data->axis[axis_num]); axis_data = &(emcmot_hal_data->axis[axis_num]);
// disallow accel bogus fractions
if ( (*(axis_data->ajog_accel_fraction) > 1)
|| (*(axis_data->ajog_accel_fraction) < 0) ) {
aaccel_limit = axis->acc_limit;
} else {
aaccel_limit = *(axis_data->ajog_accel_fraction) * axis->acc_limit;
}
new_ajog_counts = *(axis_data->ajog_counts); new_ajog_counts = *(axis_data->ajog_counts);
delta = new_ajog_counts - axis->old_ajog_counts; delta = new_ajog_counts - axis->old_ajog_counts;
axis->old_ajog_counts = new_ajog_counts; axis->old_ajog_counts = new_ajog_counts;
@ -1025,7 +1043,7 @@ static void handle_ajogwheels(void)
if ( *(axis_data->ajog_vel_mode) ) { if ( *(axis_data->ajog_vel_mode) ) {
double v = axis->vel_limit; double v = axis->vel_limit;
/* compute stopping distance at max speed */ /* compute stopping distance at max speed */
stop_dist = v * v / ( 2 * axis->acc_limit); stop_dist = v * v / ( 2 * aaccel_limit);
/* if commanded position leads the actual position by more /* if commanded position leads the actual position by more
than stopping distance, discard excess command */ than stopping distance, discard excess command */
if ( pos > axis->pos_cmd + stop_dist ) { if ( pos > axis->pos_cmd + stop_dist ) {
@ -1038,7 +1056,7 @@ static void handle_ajogwheels(void)
if (pos < axis->min_pos_limit) { break; } if (pos < axis->min_pos_limit) { break; }
axis->teleop_tp.pos_cmd = pos; axis->teleop_tp.pos_cmd = pos;
axis->teleop_tp.max_vel = axis->vel_limit; axis->teleop_tp.max_vel = axis->vel_limit;
axis->teleop_tp.max_acc = axis->acc_limit; axis->teleop_tp.max_acc = aaccel_limit;
axis->wheel_ajog_active = 1; axis->wheel_ajog_active = 1;
axis->teleop_tp.enable = 1; axis->teleop_tp.enable = 1;
} }

View file

@ -74,6 +74,7 @@ typedef struct {
hal_s32_t *jjog_counts; /* WPI: jogwheel position input */ hal_s32_t *jjog_counts; /* WPI: jogwheel position input */
hal_bit_t *jjog_enable; /* RPI: enable jogwheel */ hal_bit_t *jjog_enable; /* RPI: enable jogwheel */
hal_float_t *jjog_scale; /* RPI: distance to jog on each count */ hal_float_t *jjog_scale; /* RPI: distance to jog on each count */
hal_float_t *jjog_accel_fraction; /* RPI: to limit wheel jog accel */
hal_bit_t *jjog_vel_mode; /* RPI: true for "velocity mode" jogwheel */ hal_bit_t *jjog_vel_mode; /* RPI: true for "velocity mode" jogwheel */
} joint_hal_t; } joint_hal_t;
@ -88,6 +89,7 @@ typedef struct {
hal_s32_t *ajog_counts; /* WPI: jogwheel position input */ hal_s32_t *ajog_counts; /* WPI: jogwheel position input */
hal_bit_t *ajog_enable; /* RPI: enable jogwheel */ hal_bit_t *ajog_enable; /* RPI: enable jogwheel */
hal_float_t *ajog_scale; /* RPI: distance to jog on each count */ hal_float_t *ajog_scale; /* RPI: distance to jog on each count */
hal_float_t *ajog_accel_fraction; /* RPI: to limit wheel jog accel */
hal_bit_t *ajog_vel_mode; /* RPI: true for "velocity mode" jogwheel */ hal_bit_t *ajog_vel_mode; /* RPI: true for "velocity mode" jogwheel */
hal_bit_t *kb_ajog_active; /* RPI: executing keyboard jog */ hal_bit_t *kb_ajog_active; /* RPI: executing keyboard jog */
hal_bit_t *wheel_ajog_active;/* RPI: executing handwheel jog */ hal_bit_t *wheel_ajog_active;/* RPI: executing handwheel jog */

View file

@ -554,6 +554,9 @@ static int export_joint(int num, joint_hal_t * addr)
if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->homing), mot_comp_id, "joint.%d.homing", num)) != 0) return retval; if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->homing), mot_comp_id, "joint.%d.homing", num)) != 0) return retval;
if ((retval = hal_pin_s32_newf(HAL_OUT, &(addr->home_state), mot_comp_id, "joint.%d.home-state", num)) != 0) return retval; if ((retval = hal_pin_s32_newf(HAL_OUT, &(addr->home_state), mot_comp_id, "joint.%d.home-state", num)) != 0) return retval;
if ((retval = hal_pin_float_newf(HAL_IN,&(addr->jjog_accel_fraction), mot_comp_id,"joint.%d.jog-accel-fraction", num)) != 0) return retval;
*addr->jjog_accel_fraction = 1.0; // fraction of accel for wheel jjogs
if ( unlock_joints_mask & (1 << num) ) { if ( unlock_joints_mask & (1 << num) ) {
// these pins may be needed for rotary joints // these pins may be needed for rotary joints
rtapi_print_msg(RTAPI_MSG_WARN,"motion.c: Creating unlock hal pins for joint %d\n",num); rtapi_print_msg(RTAPI_MSG_WARN,"motion.c: Creating unlock hal pins for joint %d\n",num);
@ -579,6 +582,9 @@ static int export_axis(char c, axis_hal_t * addr)
if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->kb_ajog_active), mot_comp_id,"axis.%c.kb-jog-active", c)) != 0) return retval; if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->kb_ajog_active), mot_comp_id,"axis.%c.kb-jog-active", c)) != 0) return retval;
if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->wheel_ajog_active),mot_comp_id,"axis.%c.wheel-jog-active", c)) != 0) return retval; if ((retval = hal_pin_bit_newf(HAL_OUT, &(addr->wheel_ajog_active),mot_comp_id,"axis.%c.wheel-jog-active", c)) != 0) return retval;
if ((retval = hal_pin_float_newf(HAL_IN,&(addr->ajog_accel_fraction), mot_comp_id,"axis.%c.jog-accel-fraction", c)) != 0) return retval;
*addr->ajog_accel_fraction = 1.0; // fraction of accel for wheel ajogs
rtapi_set_msg_level(msg); rtapi_set_msg_level(msg);
return 0; return 0;
} }