tp.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,046 行 · 第 1/3 页
C
1,046 行
/********************************************************************* Description: tp.c* Trajectory planner based on TC elements** Derived from a work by Fred Proctor & Will Shackleford** Author:* License: GPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.********************************************************************/#ifdef ULAPI#include <stdio.h>#include <stdlib.h>#endif#include "rtapi.h" /* rtapi_print_msg */#include "rtapi_string.h" /* NULL */#include "posemath.h"#include "tc.h"#include "tp.h"#include "rtapi_math.h"#include "../motion/motion.h"#include "motion_debug.h"extern emcmot_status_t *emcmotStatus;extern emcmot_debug_t *emcmotDebug;int output_chan = 0;int tpCreate(TP_STRUCT * tp, int _queueSize, TC_STRUCT * tcSpace){ if (0 == tp) { return -1; } if (_queueSize <= 0) { tp->queueSize = TP_DEFAULT_QUEUE_SIZE; } else { tp->queueSize = _queueSize; } /* create the queue */ if (-1 == tcqCreate(&tp->queue, tp->queueSize, tcSpace)) { return -1; } /* init the rest of our data */ return tpInit(tp);}/* tpClear() is a "soft init" in the sense that the TP_STRUCT configuration parameters (cycleTime, vMax, and aMax) are left alone, but the queue is cleared, and the flags are set to an empty, ready queue. The currentPos is left alone, and goalPos is set to this position. This function is intended to put the motion queue in the state it would be if all queued motions finished at the current position. */int tpClear(TP_STRUCT * tp){ tcqInit(&tp->queue); tp->goalPos.tran.x = tp->currentPos.tran.x; tp->goalPos.tran.y = tp->currentPos.tran.y; tp->goalPos.tran.z = tp->currentPos.tran.z; tp->goalPos.a = tp->currentPos.a; tp->goalPos.b = tp->currentPos.b; tp->goalPos.c = tp->currentPos.c; tp->nextId = 0; tp->execId = 0; tp->motionType = 0; tp->termCond = TC_TERM_COND_BLEND; tp->tolerance = 0.0; tp->done = 1; tp->depth = tp->activeDepth = 0; tp->aborting = 0; tp->pausing = 0; tp->vScale = emcmotStatus->net_feed_scale; tp->synchronized = 0; tp->uu_per_rev = 0.0; emcmotStatus->spindleSync = 0; return 0;}int tpInit(TP_STRUCT * tp){ tp->cycleTime = 0.0; tp->vLimit = 0.0; tp->vScale = 1.0; tp->aMax = 0.0; tp->vMax = 0.0; tp->ini_maxvel = 0.0; tp->wMax = 0.0; tp->wDotMax = 0.0; tp->currentPos.tran.x = 0.0; tp->currentPos.tran.y = 0.0; tp->currentPos.tran.z = 0.0; tp->currentPos.a = 0.0; tp->currentPos.b = 0.0; tp->currentPos.c = 0.0; return tpClear(tp);}int tpSetCycleTime(TP_STRUCT * tp, double secs){ if (0 == tp || secs <= 0.0) { return -1; } tp->cycleTime = secs; return 0;}// This is called before adding lines or circles, specifying// vMax (the velocity requested by the F word) and// ini_maxvel, the max velocity possible before meeting// a machine constraint caused by an AXIS's max velocity.// (the TP is allowed to go up to this high when feed // override >100% is requested) These settings apply to// subsequent moves until changed.int tpSetVmax(TP_STRUCT * tp, double vMax, double ini_maxvel){ if (0 == tp || vMax <= 0.0 || ini_maxvel <= 0.0) { return -1; } tp->vMax = vMax; tp->ini_maxvel = ini_maxvel; return 0;}// I think this is the [TRAJ] max velocity. This should// be the max velocity of the TOOL TIP, not necessarily// any particular axis. This applies to subsequent moves// until changed.int tpSetVlimit(TP_STRUCT * tp, double vLimit){ if (0 == tp || vLimit <= 0.0) { return -1; } tp->vLimit = vLimit; return 0;}// Set max accelint tpSetAmax(TP_STRUCT * tp, double aMax){ if (0 == tp || aMax <= 0.0) { return -1; } tp->aMax = aMax; return 0;}/* tpSetId() sets the id that will be used for the next appended motions. nextId is incremented so that the next time a motion is appended its id will be one more than the previous one, modulo a signed int. If you want your own ids for each motion, call this before each motion you append and stick what you want in here. */int tpSetId(TP_STRUCT * tp, int id){ if (0 == tp) { return -1; } tp->nextId = id; return 0;}/* tpGetExecId() returns the id of the last motion that is currently executing. */int tpGetExecId(TP_STRUCT * tp){ if (0 == tp) { return -1; } return tp->execId;}/* tpSetTermCond(tp, cond) sets the termination condition for all subsequent queued moves. If cond is TC_TERM_STOP, motion comes to a stop before a subsequent move begins. If cond is TC_TERM_BLEND, the following move is begun when the current move decelerates. */int tpSetTermCond(TP_STRUCT * tp, int cond, double tolerance){ if (0 == tp) { return -1; } if (cond != TC_TERM_COND_STOP && cond != TC_TERM_COND_BLEND) { return -1; } tp->termCond = cond; tp->tolerance = tolerance; return 0;}// Used to tell the tp the initial position. It sets// the current position AND the goal position to be the same. // Used only at TP initialization and when switching modes.int tpSetPos(TP_STRUCT * tp, EmcPose pos){ if (0 == tp) { return -1; } tp->currentPos = pos; tp->goalPos = pos; return 0;}int tpAddRigidTap(TP_STRUCT *tp, EmcPose end, double vel, double ini_maxvel, double acc, unsigned char enables) { TC_STRUCT tc; PmLine line_xyz; PmPose start_xyz, end_xyz; PmCartesian abc, uvw; PmQuaternion identity_quat = { 1.0, 0.0, 0.0, 0.0 }; if (!tp) { rtapi_print_msg(RTAPI_MSG_ERR, "TP is null\n"); return -1; } if (tp->aborting) { rtapi_print_msg(RTAPI_MSG_ERR, "TP is aborting\n"); return -1; } start_xyz.tran = tp->goalPos.tran; end_xyz.tran = end.tran; start_xyz.rot = identity_quat; end_xyz.rot = identity_quat; // abc cannot move abc.x = tp->goalPos.a; abc.y = tp->goalPos.b; abc.z = tp->goalPos.c; uvw.x = tp->goalPos.u; uvw.y = tp->goalPos.v; uvw.z = tp->goalPos.w; pmLineInit(&line_xyz, start_xyz, end_xyz); tc.cycle_time = tp->cycleTime; tc.coords.rigidtap.reversal_target = line_xyz.tmag; // allow 10 turns of the spindle to stop - we don't want to just go on forever tc.target = line_xyz.tmag + 10. * tp->uu_per_rev; tc.progress = 0.0; tc.reqvel = vel; tc.maxaccel = acc; tc.feed_override = 0.0; tc.maxvel = ini_maxvel; tc.id = tp->nextId; tc.active = 0; tc.coords.rigidtap.xyz = line_xyz; tc.coords.rigidtap.abc = abc; tc.coords.rigidtap.uvw = uvw; tc.coords.rigidtap.state = TAPPING; tc.motion_type = TC_RIGIDTAP; tc.canon_motion_type = 0; tc.blend_with_next = 0; tc.tolerance = tp->tolerance; if(!tp->synchronized) { rtapi_print_msg(RTAPI_MSG_ERR, "Cannot add unsynchronized rigid tap move.\n"); return -1; } tc.synchronized = tp->synchronized; tc.uu_per_rev = tp->uu_per_rev; tc.velocity_mode = tp->velocity_mode; tc.enables = enables; if (tcqPut(&tp->queue, tc) == -1) { rtapi_print_msg(RTAPI_MSG_ERR, "tcqPut failed.\n"); return -1; } // do not change tp->goalPos here, // since this move will end just where it started tp->done = 0; tp->depth = tcqLen(&tp->queue); tp->nextId++; return 0;}// Add a straight line to the tc queue. This is a coordinated// move in any or all of the six axes. it goes from the end// of the previous move to the new end specified here at the// currently-active accel and vel settings from the tp struct.int tpAddLine(TP_STRUCT * tp, EmcPose end, int type, double vel, double ini_maxvel, double acc, unsigned char enables){ TC_STRUCT tc; PmLine line_xyz, line_uvw, line_abc; PmPose start_xyz, end_xyz; PmPose start_uvw, end_uvw; PmPose start_abc, end_abc; PmQuaternion identity_quat = { 1.0, 0.0, 0.0, 0.0 }; if (!tp) { rtapi_print_msg(RTAPI_MSG_ERR, "TP is null\n"); return -1; } if (tp->aborting) { rtapi_print_msg(RTAPI_MSG_ERR, "TP is aborting\n"); return -1; } start_xyz.tran = tp->goalPos.tran; end_xyz.tran = end.tran; start_uvw.tran.x = tp->goalPos.u; start_uvw.tran.y = tp->goalPos.v; start_uvw.tran.z = tp->goalPos.w;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?