/*---------------------------------------------------------------------- This work derived from alex joni's halui.cc Copyright: 2013,2014 Author: Dewey Garrett This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ----------------------------------------------------------------------*/ #include "rcs_print.hh" #include "emc.hh" #include "emcglb.h" #include #include "hal.h" #include "rtapi.h" #include "inihal.hh" #include "iniaxis.hh" #include "inispindle.hh" static int debug=0; static int comp_id; extern value_inihal_data old_inihal_data; static ptr_inihal_data *the_inihal_data; #define PREFIX "ini." #define EPSILON .00001 #define CLOSE(a,b,eps) ((a)-(b) < +(eps) && (a)-(b) > -(eps)) #define NEW(NAME) new_inihal_data.NAME #define CHANGED(NAME) \ ((old_inihal_data.NAME) - (new_inihal_data.NAME) > +(EPSILON)) \ || \ ((old_inihal_data.NAME) - (new_inihal_data.NAME) < -(EPSILON)) #define CHANGED_IDX(NAME,IDX) \ ((old_inihal_data.NAME[IDX]) - (new_inihal_data.NAME[IDX]) > +(EPSILON)) \ || \ ((old_inihal_data.NAME[IDX]) - (new_inihal_data.NAME[IDX]) < -(EPSILON)) #define UPDATE(NAME) old_inihal_data.NAME = new_inihal_data.NAME #define UPDATE_IDX(NAME,IDX) old_inihal_data.NAME[IDX] = new_inihal_data.NAME[IDX] #define SHOW_CHANGE(NAME) \ fprintf(stderr,"Changed: "#NAME" %g-->%g\n",old_inihal_data.NAME, \ new_inihal_data.NAME); #define SHOW_CHANGE_ARC_BLEND() \ fprintf(stderr,"Changed: blend_enable: %d-->%d\n"\ " blend_fallback_enable: %d-->%d\n"\ " optimization_depth: %d-->%d\n"\ " gap_cycles: %f-->%f\n"\ " ramp_freq: %f-->%f\n"\ ,old_inihal_data.traj_arc_blend_enable \ ,new_inihal_data.traj_arc_blend_enable \ ,old_inihal_data.traj_arc_blend_fallback_enable \ ,new_inihal_data.traj_arc_blend_fallback_enable \ ,old_inihal_data.traj_arc_blend_optimization_depth \ ,new_inihal_data.traj_arc_blend_optimization_depth \ ,old_inihal_data.traj_arc_blend_gap_cycles \ ,new_inihal_data.traj_arc_blend_gap_cycles \ ,old_inihal_data.traj_arc_blend_ramp_freq \ ,new_inihal_data.traj_arc_blend_ramp_freq \ ); #define SHOW_CHANGE_IDX(NAME,IDX) \ fprintf(stderr,"Changed: "#NAME"[%d] %g-->%g\n",IDX,old_inihal_data.NAME[IDX], \ new_inihal_data.NAME[IDX]); #define SHOW_CHANGE_IDX_INT(NAME,IDX) \ fprintf(stderr,"Changed: "#NAME"[%d] %d-->%d\n",IDX,old_inihal_data.NAME[IDX], \ new_inihal_data.NAME[IDX]); #define MAKE_BIT_PIN(NAME,DIR) \ do { \ retval = hal_pin_bit_newf(DIR,&(the_inihal_data->NAME),comp_id,PREFIX#NAME); \ if (retval < 0) return retval; \ } while (0) #define MAKE_S32_PIN(NAME,DIR) \ do { \ retval = hal_pin_s32_newf(DIR,&(the_inihal_data->NAME),comp_id,PREFIX#NAME); \ if (retval < 0) return retval; \ } while (0) #define MAKE_S32_PIN_IDX(NAME,HALPIN_NAME,DIR,IDX) \ do { \ retval = hal_pin_s32_newf(DIR,&(the_inihal_data->NAME[IDX]),\ comp_id,PREFIX"%d."#HALPIN_NAME,IDX); \ if (retval < 0) return retval; \ } while (0) #define MAKE_FLOAT_PIN(NAME,DIR) \ do { \ retval = hal_pin_float_newf(DIR,&(the_inihal_data->NAME),comp_id,PREFIX#NAME); \ if (retval < 0) return retval; \ } while (0) #define MAKE_FLOAT_PIN_IDX(NAME,HALPIN_NAME,DIR,IDX) \ do { \ retval = hal_pin_float_newf(DIR,&(the_inihal_data->NAME[IDX]),\ comp_id,PREFIX"%d."#HALPIN_NAME,IDX); \ if (retval < 0) return retval; \ } while (0) #define MAKE_FLOAT_PIN_LETTER(NAME,HALPIN_NAME,DIR,IDX,LETTER) \ do { \ retval = hal_pin_float_newf(DIR,&(the_inihal_data->NAME[IDX]),\ comp_id,PREFIX"%c."#HALPIN_NAME,LETTER); \ if (retval < 0) return retval; \ } while (0) #define INIT_PIN(NAME) *(the_inihal_data->NAME) = old_inihal_data.NAME; int ini_hal_exit(void) { hal_exit(comp_id); comp_id = -1; return 0; } int ini_hal_init(int numjoints) { int retval; comp_id = hal_init("inihal"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ini_hal_init: ERROR: hal_init() failed\n"); return -1; } the_inihal_data = (ptr_inihal_data *) hal_malloc(sizeof(ptr_inihal_data)); if (the_inihal_data == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "ini_hal_init: ERROR: hal_malloc() failed\n"); hal_exit(comp_id); return -1; } for (int idx = 0; idx < numjoints; idx++) { MAKE_FLOAT_PIN_IDX(joint_backlash,backlash,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_ferror,ferror,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_min_ferror,min_ferror,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_min_limit,min_limit,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_max_limit,max_limit,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_max_velocity,max_velocity,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_max_acceleration,max_acceleration,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_home,home,HAL_IN,idx); MAKE_FLOAT_PIN_IDX(joint_home_offset,home_offset,HAL_IN,idx); MAKE_S32_PIN_IDX( joint_home_sequence,home_sequence,HAL_IN,idx); } for (int idx = 0; idx < EMCMOT_MAX_AXIS; idx++) { char letter = "xyzabcuvw"[idx]; MAKE_FLOAT_PIN_LETTER(axis_min_limit,min_limit,HAL_IN,idx,letter); MAKE_FLOAT_PIN_LETTER(axis_max_limit,max_limit,HAL_IN,idx,letter); MAKE_FLOAT_PIN_LETTER(axis_max_velocity,max_velocity,HAL_IN,idx,letter); MAKE_FLOAT_PIN_LETTER(axis_max_acceleration,max_acceleration,HAL_IN,idx,letter); } MAKE_FLOAT_PIN(traj_default_velocity,HAL_IN); MAKE_FLOAT_PIN(traj_max_velocity,HAL_IN); MAKE_FLOAT_PIN(traj_default_acceleration,HAL_IN); MAKE_FLOAT_PIN(traj_max_acceleration,HAL_IN); MAKE_BIT_PIN(traj_arc_blend_enable,HAL_IN); MAKE_BIT_PIN(traj_arc_blend_fallback_enable,HAL_IN); MAKE_S32_PIN(traj_arc_blend_optimization_depth,HAL_IN); MAKE_FLOAT_PIN(traj_arc_blend_gap_cycles,HAL_IN); MAKE_FLOAT_PIN(traj_arc_blend_ramp_freq,HAL_IN); MAKE_FLOAT_PIN(traj_arc_blend_tangent_kink_ratio,HAL_IN); hal_ready(comp_id); return 0; } // ini_hal_init() int ini_hal_init_pins(int numjoints) { INIT_PIN(traj_default_velocity); INIT_PIN(traj_max_velocity); INIT_PIN(traj_default_acceleration); INIT_PIN(traj_max_acceleration); INIT_PIN(traj_arc_blend_enable); INIT_PIN(traj_arc_blend_fallback_enable); INIT_PIN(traj_arc_blend_optimization_depth); INIT_PIN(traj_arc_blend_gap_cycles); INIT_PIN(traj_arc_blend_ramp_freq); INIT_PIN(traj_arc_blend_tangent_kink_ratio); for (int idx = 0; idx < numjoints; idx++) { INIT_PIN(joint_backlash[idx]); INIT_PIN(joint_ferror[idx]); INIT_PIN(joint_min_ferror[idx]); INIT_PIN(joint_min_limit[idx]); INIT_PIN(joint_max_limit[idx]); INIT_PIN(joint_max_velocity[idx]); INIT_PIN(joint_max_acceleration[idx]); INIT_PIN(joint_home[idx]); INIT_PIN(joint_home_offset[idx]); INIT_PIN(joint_home_sequence[idx]); } for (int idx = 0; idx < EMCMOT_MAX_AXIS; idx++) { INIT_PIN(axis_min_limit[idx]); INIT_PIN(axis_max_limit[idx]); INIT_PIN(axis_max_velocity[idx]); INIT_PIN(axis_max_acceleration[idx]); } return 0; } // ini_hal_init_pins() static void copy_hal_data(const ptr_inihal_data &i, value_inihal_data &j) { int x; #define FIELD(t,f) j.f = (i.f)?*i.f:0; #define ARRAY(t,f,n) do { for (x = 0; x < n; x++) j.f[x] = (i.f[x])?*i.f[x]:0; } while (0); HAL_FIELDS #undef FIELD #undef ARRAY } // copy_hal_data() int check_ini_hal_items(int numjoints) { value_inihal_data new_inihal_data_mutable; copy_hal_data(*the_inihal_data, new_inihal_data_mutable); const value_inihal_data &new_inihal_data = new_inihal_data_mutable; if (CHANGED(traj_default_velocity)) { if (debug) SHOW_CHANGE(traj_default_velocity) UPDATE(traj_default_velocity); if (0 != emcTrajSetVelocity(0, NEW(traj_default_velocity))) { rcs_print("check_ini_hal_items:bad return value from emcTrajSetVelocity\n"); } } if (CHANGED(traj_max_velocity)) { if (debug) SHOW_CHANGE(traj_max_velocity) UPDATE(traj_max_velocity); if (0 != emcTrajSetMaxVelocity(NEW(traj_max_velocity))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print("check_ini_hal_items:bad return value from emcTrajSetMaxVelocity\n"); } } } if (CHANGED(traj_default_acceleration)) { if (debug) SHOW_CHANGE(traj_default_acceleration) UPDATE(traj_default_acceleration); if (0 != emcTrajSetAcceleration(NEW(traj_default_acceleration))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print("check_ini_hal_items:bad return value from emcTrajSetAcceleration\n"); } } } if (CHANGED(traj_max_acceleration)) { if (debug) SHOW_CHANGE(traj_max_acceleration) UPDATE(traj_max_acceleration); if (0 != emcTrajSetMaxAcceleration(NEW(traj_max_acceleration))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print("check_ini_hal_items:bad return value from emcTrajSetMaxAcceleration\n"); } } } if ( CHANGED(traj_arc_blend_enable) || CHANGED(traj_arc_blend_fallback_enable) || CHANGED(traj_arc_blend_optimization_depth) || CHANGED(traj_arc_blend_gap_cycles) || CHANGED(traj_arc_blend_ramp_freq) || CHANGED(traj_arc_blend_tangent_kink_ratio) ) { if (debug) SHOW_CHANGE_ARC_BLEND() UPDATE(traj_arc_blend_enable); UPDATE(traj_arc_blend_fallback_enable); UPDATE(traj_arc_blend_optimization_depth); UPDATE(traj_arc_blend_gap_cycles); UPDATE(traj_arc_blend_ramp_freq); UPDATE(traj_arc_blend_tangent_kink_ratio); if (0 != emcSetupArcBlends(old_inihal_data.traj_arc_blend_enable ,old_inihal_data.traj_arc_blend_fallback_enable ,old_inihal_data.traj_arc_blend_optimization_depth ,old_inihal_data.traj_arc_blend_gap_cycles ,old_inihal_data.traj_arc_blend_ramp_freq ,old_inihal_data.traj_arc_blend_tangent_kink_ratio )) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print("bad return value from emcSetupArcBlends\n"); } return -1; } } for (int idx = 0; idx < numjoints; idx++) { if (CHANGED_IDX(joint_backlash,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_backlash,idx); UPDATE_IDX(joint_backlash,idx); if (0 != emcJointSetBacklash(idx,NEW(joint_backlash[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print("check_ini_hal_items:bad return value from emcJointSetBacklash\n"); } } } if (CHANGED_IDX(joint_min_limit,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_min_limit,idx); UPDATE_IDX(joint_min_limit,idx); if (0 != emcJointSetMinPositionLimit(idx,NEW(joint_min_limit[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetMinPositionLimit\n"); } } } if (CHANGED_IDX(joint_max_limit,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_max_limit,idx); UPDATE_IDX(joint_max_limit,idx); if (0 != emcJointSetMaxPositionLimit(idx,NEW(joint_max_limit[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetMaxPositionLimit\n"); } } } if (CHANGED_IDX(joint_max_velocity,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_max_velocity,idx); UPDATE_IDX(joint_max_velocity,idx); if (0 != emcJointSetMaxVelocity(idx, NEW(joint_max_velocity[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetMaxVelocity\n"); } } } if (CHANGED_IDX(joint_max_acceleration,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_max_acceleration,idx); UPDATE_IDX(joint_max_acceleration,idx); if (0 != emcJointSetMaxAcceleration(idx, NEW(joint_max_acceleration[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetMaxAcceleration\n"); } } } if ( CHANGED_IDX(joint_home,idx) || CHANGED_IDX(joint_home_offset,idx) || CHANGED_IDX(joint_home_sequence,idx) ) { if (debug) { SHOW_CHANGE_IDX(joint_home,idx); SHOW_CHANGE_IDX(joint_home_offset,idx); SHOW_CHANGE_IDX_INT(joint_home_sequence,idx); } UPDATE_IDX(joint_home,idx); UPDATE_IDX(joint_home_offset,idx); UPDATE_IDX(joint_home_sequence,idx); if (0 != emcJointUpdateHomingParams(idx, NEW(joint_home[idx]), NEW(joint_home_offset[idx]), NEW(joint_home_sequence[idx])) ) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointUpdateHomingParams\n"); } } } if (CHANGED_IDX(joint_ferror,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_ferror,idx); UPDATE_IDX(joint_ferror,idx); if (0 != emcJointSetFerror(idx,NEW(joint_ferror[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetFerror\n"); } } } if (CHANGED_IDX(joint_min_ferror,idx) ) { if (debug) SHOW_CHANGE_IDX(joint_min_ferror,idx); UPDATE_IDX(joint_min_ferror,idx); if (0 != emcJointSetMinFerror(idx,NEW(joint_min_ferror[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcJointSetMinFerror\n"); } } } } // numjoints for (int idx = 0; idx < EMCMOT_MAX_AXIS; idx++) { if (CHANGED_IDX(axis_min_limit,idx) ) { if (debug) SHOW_CHANGE_IDX(axis_min_limit,idx); UPDATE_IDX(axis_min_limit,idx); if (0 != emcAxisSetMinPositionLimit(idx,NEW(axis_min_limit[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcAxisSetMinPositionLimit\n"); } } } if (CHANGED_IDX(axis_max_limit,idx) ) { if (debug) SHOW_CHANGE_IDX(axis_max_limit,idx); UPDATE_IDX(axis_max_limit,idx); if (0 != emcAxisSetMaxPositionLimit(idx,NEW(axis_max_limit[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcAxisSetMaxPositionLimit\n"); } } } if (CHANGED_IDX(axis_max_velocity,idx) ) { if (debug) SHOW_CHANGE_IDX(axis_max_velocity,idx); UPDATE_IDX(axis_max_velocity,idx); if (0 != emcAxisSetMaxVelocity(idx, (1 - ext_offset_a_or_v_ratio[idx]) * NEW(axis_max_velocity[idx]), ( ext_offset_a_or_v_ratio[idx]) * NEW(axis_max_velocity[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcAxisSetMaxVelocity\n"); } } } if (CHANGED_IDX(axis_max_acceleration,idx) ) { if (debug) SHOW_CHANGE_IDX(axis_max_acceleration,idx); UPDATE_IDX(axis_max_acceleration,idx); if (0 != emcAxisSetMaxAcceleration(idx, (1 - ext_offset_a_or_v_ratio[idx]) * NEW(axis_max_acceleration[idx]), ( ext_offset_a_or_v_ratio[idx]) * NEW(axis_max_acceleration[idx]))) { if (emc_debug & EMC_DEBUG_CONFIG) { rcs_print_error("check_ini_hal_items:bad return from emcAxisSetMaxAcceleration\n"); } } } } // EMCMOT_MAX_AXIS return 0; } // check_ini_hal_items // vim: sts=4 sw=4 et