📄 motion.c
字号:
if (retval != RTAPI_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: rtapi_shmem_getptr failed, returned %d\n", retval); return -1; } /* zero shared memory before doing anything else. */ memset(emcmotStruct, 0, sizeof(emcmot_struct_t)); /* we'll reference emcmotStruct directly */ emcmotCommand = &emcmotStruct->command; emcmotStatus = &emcmotStruct->status; emcmotConfig = &emcmotStruct->config; emcmotDebug = &emcmotStruct->debug; emcmotInternal = &emcmotStruct->internal; emcmotError = &emcmotStruct->error; /* init error struct */ emcmotErrorInit(emcmotError); /* init command struct */ emcmotCommand->head = 0; emcmotCommand->command = 0; emcmotCommand->commandNum = 0; emcmotCommand->tail = 0; emcmotCommand->spindlesync = 0.0; /* init status struct */ emcmotStatus->head = 0; emcmotStatus->commandEcho = 0; emcmotStatus->commandNumEcho = 0; emcmotStatus->commandStatus = 0; /* init more stuff */ emcmotDebug->head = 0; emcmotConfig->head = 0; emcmotStatus->motionFlag = 0; SET_MOTION_ERROR_FLAG(0); SET_MOTION_COORD_FLAG(0); SET_MOTION_TELEOP_FLAG(0); emcmotDebug->split = 0; emcmotStatus->heartbeat = 0; emcmotStatus->computeTime = 0.0; emcmotConfig->numAxes = EMCMOT_MAX_AXIS; emcmotStatus->carte_pos_cmd.tran.x = 0.0; emcmotStatus->carte_pos_cmd.tran.y = 0.0; emcmotStatus->carte_pos_cmd.tran.z = 0.0; emcmotStatus->carte_pos_fb.tran.x = 0.0; emcmotStatus->carte_pos_fb.tran.y = 0.0; emcmotStatus->carte_pos_fb.tran.z = 0.0; emcmotStatus->vel = VELOCITY; emcmotConfig->limitVel = VELOCITY; emcmotStatus->acc = ACCELERATION; emcmotStatus->qVscale = 1.0; emcmotStatus->id = 0; emcmotStatus->depth = 0; emcmotStatus->activeDepth = 0; emcmotStatus->paused = 0; emcmotStatus->overrideLimits = 0; SET_MOTION_INPOS_FLAG(1); SET_MOTION_ENABLE_FLAG(0); emcmotConfig->kinematics_type = kinType; emcmotDebug->oldPos = emcmotStatus->carte_pos_cmd; emcmotDebug->oldVel.tran.x = 0.0; emcmotDebug->oldVel.tran.y = 0.0; emcmotDebug->oldVel.tran.z = 0.0; emcmot_config_change(); /* init pointer to joint structs */#ifdef STRUCTS_IN_SHMEM joints = &(emcmotDebug->joints[0]);#else joints = &(joint_array[0]);#endif /* init per-axis stuff */ for (joint_num = 0; joint_num < EMCMOT_MAX_AXIS; joint_num++) { /* point to structure for this joint */ joint = &joints[joint_num]; /* init the config fields with some "reasonable" defaults" */ joint->type = 0; joint->max_pos_limit = 1.0; joint->min_pos_limit = -1.0; joint->vel_limit = 1.0; joint->acc_limit = 1.0; joint->min_ferror = 0.01; joint->max_ferror = 1.0; joint->switch_flags = 0; joint->home_search_vel = 0.0; joint->home_latch_vel = 0.0; joint->home_offset = 0.0; joint->home = 0.0; joint->home_flags = 0; joint->backlash = 0.0; /* init compensation struct - leave out the avgint, nominal, forward, and reverse, since these can't be zero and the total flag prevents their use anyway */ joint->comp.total = 0; joint->comp.alter = 0.0; /* init status info */ joint->flag = 0; joint->coarse_pos = 0.0; joint->pos_cmd = 0.0; joint->vel_cmd = 0.0; joint->backlash_corr = 0.0; joint->backlash_filt = 0.0; joint->motor_pos_cmd = 0.0; joint->motor_pos_fb = 0.0; joint->pos_fb = 0.0; joint->ferror = 0.0; joint->ferror_limit = joint->min_ferror; joint->ferror_high_mark = 0.0; /* init internal info */ cubicInit(&(joint->cubic)); /* init misc other stuff in joint structure */ joint->big_vel = 10.0 * joint->vel_limit; joint->home_state = 0; /* init joint flags (reduntant, since flag = 0 */ SET_JOINT_ENABLE_FLAG(joint, 0); SET_JOINT_ACTIVE_FLAG(joint, 0); SET_JOINT_NSL_FLAG(joint, 0); SET_JOINT_PSL_FLAG(joint, 0); SET_JOINT_NHL_FLAG(joint, 0); SET_JOINT_PHL_FLAG(joint, 0); SET_JOINT_INPOS_FLAG(joint, 1); SET_JOINT_HOMING_FLAG(joint, 0); SET_JOINT_HOMED_FLAG(joint, 0); SET_JOINT_FERROR_FLAG(joint, 0); SET_JOINT_FAULT_FLAG(joint, 0); SET_JOINT_ERROR_FLAG(joint, 0); } /*! \todo FIXME-- add emcmotError */ /* init min-max-avg stats */ mmxavgInit(&emcmotDebug->tMmxavg, emcmotDebug->tMmxavgSpace, MMXAVG_SIZE); mmxavgInit(&emcmotDebug->sMmxavg, emcmotDebug->sMmxavgSpace, MMXAVG_SIZE); mmxavgInit(&emcmotDebug->nMmxavg, emcmotDebug->nMmxavgSpace, MMXAVG_SIZE); mmxavgInit(&emcmotDebug->yMmxavg, emcmotDebug->yMmxavgSpace, MMXAVG_SIZE); mmxavgInit(&emcmotDebug->fMmxavg, emcmotDebug->fMmxavgSpace, MMXAVG_SIZE); mmxavgInit(&emcmotDebug->fyMmxavg, emcmotDebug->fyMmxavgSpace, MMXAVG_SIZE); emcmotDebug->tMin = 0.0; emcmotDebug->tMax = 0.0; emcmotDebug->tAvg = 0.0; emcmotDebug->sMin = 0.0; emcmotDebug->sMax = 0.0; emcmotDebug->sAvg = 0.0; emcmotDebug->nMin = 0.0; emcmotDebug->nMax = 0.0; emcmotDebug->nAvg = 0.0; emcmotDebug->yMin = 0.0; emcmotDebug->yMax = 0.0; emcmotDebug->yAvg = 0.0; emcmotDebug->fyMin = 0.0; emcmotDebug->fyMax = 0.0; emcmotDebug->fyAvg = 0.0; emcmotDebug->fMin = 0.0; emcmotDebug->fMax = 0.0; emcmotDebug->fAvg = 0.0; emcmotDebug->cur_time = emcmotDebug->last_time = 0.0; emcmotDebug->start_time = etime(); emcmotDebug->running_time = 0.0; /* init motion emcmotDebug->queue */ if (-1 == tpCreate(&emcmotDebug->queue, DEFAULT_TC_QUEUE_SIZE, emcmotDebug->queueTcSpace)) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to create motion emcmotDebug->queue\n"); return -1; }// tpInit(&emcmotDebug->queue); // tpInit called from tpCreate tpSetCycleTime(&emcmotDebug->queue, emcmotConfig->trajCycleTime); tpSetPos(&emcmotDebug->queue, emcmotStatus->carte_pos_cmd); tpSetVmax(&emcmotDebug->queue, emcmotStatus->vel, emcmotStatus->vel); tpSetAmax(&emcmotDebug->queue, emcmotStatus->acc); emcmotStatus->tail = 0; rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: init_comm_buffers() complete\n"); return 0;}/* init_threads() creates realtime threads, exports functions to do the realtime control, and adds the functions to the threads.*/static int init_threads(void){ double base_period_sec, servo_period_sec, traj_period_sec; int servo_base_ratio, traj_servo_ratio; int retval; rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: init_threads() starting...\n"); /* if base_period not specified, assume same as servo_period */ if (base_period_nsec == 0) { base_period_nsec = servo_period_nsec; } /* servo period must be greater or equal to base period */ if (servo_period_nsec < base_period_nsec) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: bad servo period %d nsec\n", servo_period_nsec); return -1; } /* traj period must be at least 2x servo period */ if (traj_period_nsec < 2 * servo_period_nsec) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: bad traj period %d nsec\n", traj_period_nsec); return -1; } /* convert desired periods to floating point */ base_period_sec = base_period_nsec * 0.000000001; servo_period_sec = servo_period_nsec * 0.000000001; traj_period_sec = traj_period_nsec * 0.000000001; /* calculate period ratios, round to nearest integer */ servo_base_ratio = (servo_period_sec / base_period_sec) + 0.5; traj_servo_ratio = (traj_period_sec / servo_period_sec) + 0.5; /* revise desired periods to be integer multiples of each other */ servo_period_nsec = base_period_nsec * servo_base_ratio; traj_period_nsec = servo_period_nsec * traj_servo_ratio; /* create HAL threads for each period */ /* only create base thread if it is faster than servo thread */ if (servo_base_ratio > 1) { retval = hal_create_thread("base-thread", base_period_nsec, 0); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to create %d nsec base thread\n", base_period_nsec); return -1; } } retval = hal_create_thread("servo-thread", servo_period_nsec, 1); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to create %d nsec servo thread\n", servo_period_nsec); return -1; } retval = hal_create_thread("traj-thread", traj_period_nsec, 1); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to create %d nsec traj thread\n", traj_period_nsec); return -1; } /* export realtime functions that do the real work */ retval = hal_export_funct("motion-controller", emcmotController, 0 /* arg */ , 1 /* uses_fp */ , 0 /* reentrant */ , mot_comp_id); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to export controller function\n"); return -1; } retval = hal_export_funct("motion-command-handler", emcmotCommandHandler, 0 /* arg */ , 1 /* uses_fp */ , 0 /* reentrant */ , mot_comp_id); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to export command handler function\n"); return -1; }/*! \todo Another #if 0 */#if 0 /*! \todo FIXME - currently the traj planner is called from the controller */ /* eventually it will be a separate function */ retval = hal_export_funct("motion-traj-planner", emcmotTrajPlanner, 0 /* arg */ , 1 /* uses_fp */ , 0 /* reentrant */ , mot_comp_id); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: failed to export traj planner function\n"); return -1; }#endif /* init the time and rate using functions to affect traj, and the cubics properly, since they're coupled */ retval = setTrajCycleTime(traj_period_nsec * 0.000000001); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: setTrajCycleTime() failed\n"); return -1; } retval = setServoCycleTime(servo_period_nsec * 0.000000001); if (retval != HAL_SUCCESS) { rtapi_print_msg(RTAPI_MSG_ERR, "MOTION: setServoCycleTime() failed\n"); return -1; } rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: init_threads() complete\n"); return 0;}/* call this when setting the trajectory cycle time */static int setTrajCycleTime(double secs){ static int t; rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: setting Traj cycle time to %d nsecs\n", (long) (secs * 1e9)); /* make sure it's not zero */ if (secs <= 0.0) { return -1; } emcmot_config_change(); /* compute the interpolation rate as nearest integer to traj/servo */ emcmotConfig->interpolationRate = (int) (secs / emcmotConfig->servoCycleTime + 0.5); /* set traj planner */ tpSetCycleTime(&emcmotDebug->queue, secs); /* set the free planners, cubic interpolation rate and segment time */ for (t = 0; t < EMCMOT_MAX_AXIS; t++) { cubicSetInterpolationRate(&(joints[t].cubic), emcmotConfig->interpolationRate); } /* copy into status out */ emcmotConfig->trajCycleTime = secs; return 0;}/* call this when setting the servo cycle time */static int setServoCycleTime(double secs){ static int t; rtapi_print_msg(RTAPI_MSG_INFO, "MOTION: setting Servo cycle time to %d nsecs\n", (long) (secs * 1e9)); /* make sure it's not zero */ if (secs <= 0.0) { return -1; } emcmot_config_change(); /* compute the interpolation rate as nearest integer to traj/servo */ emcmotConfig->interpolationRate = (int) (emcmotConfig->trajCycleTime / secs + 0.5); /* set the cubic interpolation rate and PID cycle time */ for (t = 0; t < EMCMOT_MAX_AXIS; t++) { cubicSetInterpolationRate(&(joints[t].cubic), emcmotConfig->interpolationRate); cubicSetSegmentTime(&(joints[t].cubic), secs); } /* copy into status out */ emcmotConfig->servoCycleTime = secs; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -