557 lines
18 KiB
C++
557 lines
18 KiB
C++
#include <Encoder.h>
|
|
#include <avr/pgmspace.h>
|
|
|
|
#include <AccelStepper.h>
|
|
|
|
// Firmware version
|
|
const char* VERSION = "0.0.1";
|
|
|
|
const int NUM_JOINTS = 6;
|
|
|
|
/*
|
|
MOTOR DIRECTION - motor directions can be changed on the caibration page in the software but can also
|
|
be changed here: example using DM542T driver(CW) set to 1 - if using ST6600 or DM320T driver(CCW) set to 0
|
|
DEFAULT = 111011 */
|
|
|
|
const int J1rotdir = 1;
|
|
const int J2rotdir = 1;
|
|
const int J3rotdir = 1;
|
|
const int J4rotdir = 0;
|
|
const int J5rotdir = 1;
|
|
const int J6rotdir = 1;
|
|
const int ROT_DIRS[] = { J1rotdir, J2rotdir, J3rotdir, J4rotdir, J5rotdir, J6rotdir };
|
|
|
|
// approx encoder counts at rest position, 0 degree joint angle
|
|
// DEFAULTS 38681, 11264, 0, 36652, 5839, 15671
|
|
// J2 and J6 joint enc { 38681, 902, 0, 36652, 2198, 15671 }
|
|
const int REST_ENC_POSITIONS[] = { 38681, 11264, 0, 36652, 5839, 15671 };
|
|
|
|
const int J1stepPin = 0;
|
|
const int J1dirPin = 1;
|
|
const int J2stepPin = 2;
|
|
const int J2dirPin = 3;
|
|
const int J3stepPin = 4;
|
|
const int J3dirPin = 5;
|
|
const int J4stepPin = 6;
|
|
const int J4dirPin = 7;
|
|
const int J5stepPin = 8;
|
|
const int J5dirPin = 9;
|
|
const int J6stepPin = 10;
|
|
const int J6dirPin = 11;
|
|
const int TRstepPin = 12;
|
|
const int TRdirPin = 13;
|
|
const int STEP_PINS[] = { J1stepPin, J2stepPin, J3stepPin, J4stepPin, J5stepPin, J6stepPin };
|
|
const int DIR_PINS[] = { J1dirPin, J2dirPin, J3dirPin, J4dirPin, J5dirPin, J6dirPin };
|
|
|
|
// set encoder pins
|
|
Encoder J1encPos(14, 15);
|
|
Encoder J2encPos(16, 17);
|
|
Encoder J3encPos(18, 19);
|
|
Encoder J4encPos(33, 34);
|
|
Encoder J5encPos(35, 36);
|
|
Encoder J6encPos(37, 38);
|
|
Encoder JOINT_ENCODERS[] = { J1encPos, J2encPos, J3encPos, J4encPos, J5encPos, J6encPos };
|
|
// DEFAULTS { 1, 1, 1, 1, 1, 1 }
|
|
// J2 joint enc { 1, -1, 1, 1, 1, 1 }
|
|
int ENC_DIR[] = { 1, 1, 1, 1, 1, 1 }; // +1 if encoder direction matches motor direction
|
|
|
|
// set calibration limit switch pins
|
|
const int J1calPin = 27;
|
|
const int J2calPin = 28;
|
|
const int J3calPin = 29;
|
|
const int J4calPin = 30;
|
|
const int J5calPin = 31;
|
|
const int J6calPin = 32;
|
|
const int CAL_PINS[] = { J1calPin, J2calPin, J3calPin, J4calPin, J5calPin, J6calPin };
|
|
const int LIMIT_SWITCH_HIGH[] = { 1, 1, 1, 1, 1, 1 }; // to account for both NC and NO limit switches
|
|
const int CAL_DIR[] = { -1, -1, 1, -1, -1, 1 }; // joint rotation direction to limit switch
|
|
const int CAL_SPEED = 600; // motor steps per second
|
|
// DEFAULT { 1, 1, 1, 2, 1, 1 }
|
|
// J2 joint enc { 1, 10, 1, 2, 1, 1 }
|
|
const int CAL_SPEED_MULT[] = { 1, 1, 1, 2, 1, 1 }; // multiplier to account for transmission ratios
|
|
|
|
// motor and encoder steps per revolution
|
|
// DEFAULTS { 400, 400, 400, 400, 800, 400 }
|
|
// J2 motor 4000 steps per rev { 400, 4000, 400, 400, 800, 400 }
|
|
// const int MOTOR_STEPS_PER_REV[] = { 200, 200, 200, 200, 200, 200 };
|
|
const int MOTOR_STEPS_PER_REV[] = { 400, 400, 400, 400, 800, 400 };
|
|
|
|
// num of steps in range of motion of joint, may vary depending on your limit switch
|
|
// DEFAULT { 77363, 36854, 40878, 71967, 23347, 32358 }
|
|
// J2 joint enc { 77363, 2949, 40878, 71967, 4740, 32358 }
|
|
const int ENC_RANGE_STEPS[] = { 77363, 36854, 40878, 71967, 23347, 32358 };
|
|
|
|
//set encoder multiplier, encoder steps per motor step
|
|
// DEFAULT { 5.12, 5.12, 5.12, 5.12, 2.56, 5.12 }
|
|
// J2 and J5 joint enc { 5.12, 0.04096, 5.12, 5.12, 0.5197, 5.12 }
|
|
const float ENC_MULT[] = { 5.12, 5.12, 5.12, 5.12, 5.12, 5.12 };
|
|
// const float ENC_MULT[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
|
|
// DEFAULT { 227.5555555555556, 284.4444444444444, 284.4444444444444, 223.0044444444444, 56.04224675948152, 108.0888888888889 }
|
|
// J2 and J5 joint enc { 227.5555555555556, 22.75555555555556, 284.4444444444444, 223.0044444444444, 22.75555555555556, 108.0888888888889 }
|
|
const float ENC_STEPS_PER_DEG[] = { 227.5555555555556, 284.4444444444444, 284.4444444444444, 223.0044444444444, 56.04224675948152, 108.0888888888889 };
|
|
|
|
// speed and acceleration settings
|
|
float JOINT_MAX_SPEED[] = { 2.0, 2.0, 2.0, 2.0, 2.0, 2.0 }; // deg/s
|
|
float JOINT_MAX_ACCEL[] = { 5.0, 5.0, 5.0, 5.0, 5.0, 5.0 }; // deg/s^2
|
|
// DEFAULT { 1500, 1500, 1500, 2000, 1500, 1500 }
|
|
// J2 4000 steps/rev { 1500, 15000, 1500, 2000, 1500, 1500 }
|
|
int MOTOR_MAX_SPEED[] = { 5500, 1500, 1500, 1500, 1500, 1500 }; // motor steps per sec
|
|
// DEFAULT { 250, 250, 250, 250, 250, 250 }
|
|
// J2 4000 steps/rev { 250, 2500, 250, 250, 250, 250 }
|
|
int MOTOR_MAX_ACCEL[] = { 25000, 25000, 25000, 25000, 25000, 25000 }; // motor steps per sec^2
|
|
|
|
// played around with this a little but I don't see a need to use this at the moment
|
|
float MOTOR_SPEED_MULT[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; // for tuning position control
|
|
float MOTOR_ACCEL_MULT[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; // for tuning position control
|
|
|
|
AccelStepper stepperJoints[NUM_JOINTS];
|
|
|
|
enum SM { STATE_INIT, STATE_TRAJ, STATE_ERR };
|
|
SM STATE = STATE_INIT;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//MAIN
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void setup() {
|
|
// run once:
|
|
Serial.begin(115200);
|
|
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
JOINT_ENCODERS[i].write(REST_ENC_POSITIONS[i]);
|
|
}
|
|
|
|
pinMode(TRstepPin, OUTPUT);
|
|
pinMode(TRdirPin, OUTPUT);
|
|
pinMode(J1stepPin, OUTPUT);
|
|
pinMode(J1dirPin, OUTPUT);
|
|
pinMode(J2stepPin, OUTPUT);
|
|
pinMode(J2dirPin, OUTPUT);
|
|
pinMode(J3stepPin, OUTPUT);
|
|
pinMode(J3dirPin, OUTPUT);
|
|
pinMode(J4stepPin, OUTPUT);
|
|
pinMode(J4dirPin, OUTPUT);
|
|
pinMode(J5stepPin, OUTPUT);
|
|
pinMode(J5dirPin, OUTPUT);
|
|
pinMode(J6stepPin, OUTPUT);
|
|
pinMode(J6dirPin, OUTPUT);
|
|
|
|
pinMode(J1calPin, INPUT_PULLUP);
|
|
pinMode(J2calPin, INPUT_PULLUP);
|
|
pinMode(J3calPin, INPUT_PULLUP);
|
|
pinMode(J4calPin, INPUT_PULLUP);
|
|
pinMode(J5calPin, INPUT_PULLUP);
|
|
pinMode(J6calPin, INPUT_PULLUP);
|
|
|
|
digitalWrite(TRstepPin, HIGH);
|
|
digitalWrite(J1stepPin, HIGH);
|
|
digitalWrite(J2stepPin, HIGH);
|
|
digitalWrite(J3stepPin, HIGH);
|
|
digitalWrite(J4stepPin, HIGH);
|
|
digitalWrite(J5stepPin, HIGH);
|
|
digitalWrite(J6stepPin, HIGH);
|
|
|
|
}
|
|
|
|
bool initStateTraj(String inData)
|
|
{
|
|
// parse initialisation message
|
|
int idxVersion = inData.indexOf('A');
|
|
String softwareVersion = inData.substring(idxVersion + 1, inData.length() - 1);
|
|
int versionMatches = (softwareVersion == VERSION);
|
|
|
|
// return acknowledgement with result
|
|
String msg = String("ST") + String("A") + String(versionMatches) + String("B") + String(VERSION) + String("\n");
|
|
Serial.print(msg);
|
|
|
|
return versionMatches ? true : false;
|
|
}
|
|
|
|
void readEncPos(int* encPos)
|
|
{
|
|
/*
|
|
encPos[0] = J1encPos.read() * ENC_DIR[0];
|
|
encPos[1] = J2encPos.read() * ENC_DIR[1];
|
|
encPos[2] = J3encPos.read() * ENC_DIR[2];
|
|
encPos[3] = J4encPos.read() * ENC_DIR[3];
|
|
encPos[4] = J5encPos.read() * ENC_DIR[4];
|
|
encPos[5] = J6encPos.read() * ENC_DIR[5];
|
|
*/
|
|
encPos[0] = stepperJoints[0].currentPosition();
|
|
encPos[1] = stepperJoints[1].currentPosition();
|
|
encPos[2] = stepperJoints[2].currentPosition();
|
|
encPos[3] = stepperJoints[3].currentPosition();
|
|
encPos[4] = stepperJoints[4].currentPosition();
|
|
encPos[5] = stepperJoints[5].currentPosition();
|
|
}
|
|
|
|
void updateStepperSpeed(String inData)
|
|
{
|
|
int idxSpeedJ1 = inData.indexOf('A');
|
|
int idxAccelJ1 = inData.indexOf('B');
|
|
int idxSpeedJ2 = inData.indexOf('C');
|
|
int idxAccelJ2 = inData.indexOf('D');
|
|
int idxSpeedJ3 = inData.indexOf('E');
|
|
int idxAccelJ3 = inData.indexOf('F');
|
|
int idxSpeedJ4 = inData.indexOf('G');
|
|
int idxAccelJ4 = inData.indexOf('H');
|
|
int idxSpeedJ5 = inData.indexOf('I');
|
|
int idxAccelJ5 = inData.indexOf('J');
|
|
int idxSpeedJ6 = inData.indexOf('K');
|
|
int idxAccelJ6 = inData.indexOf('L');
|
|
|
|
JOINT_MAX_SPEED[0] = inData.substring(idxSpeedJ1 + 1, idxAccelJ1).toFloat();
|
|
JOINT_MAX_ACCEL[0] = inData.substring(idxAccelJ1 + 1, idxSpeedJ2).toFloat();
|
|
JOINT_MAX_SPEED[1] = inData.substring(idxSpeedJ2 + 1, idxAccelJ2).toFloat();
|
|
JOINT_MAX_ACCEL[1] = inData.substring(idxAccelJ2 + 1, idxSpeedJ3).toFloat();
|
|
JOINT_MAX_SPEED[2] = inData.substring(idxSpeedJ3 + 1, idxAccelJ3).toFloat();
|
|
JOINT_MAX_ACCEL[2] = inData.substring(idxAccelJ3 + 1, idxSpeedJ4).toFloat();
|
|
JOINT_MAX_SPEED[3] = inData.substring(idxSpeedJ4 + 1, idxAccelJ4).toFloat();
|
|
JOINT_MAX_ACCEL[3] = inData.substring(idxAccelJ4 + 1, idxSpeedJ5).toFloat();
|
|
JOINT_MAX_SPEED[4] = inData.substring(idxSpeedJ5 + 1, idxAccelJ5).toFloat();
|
|
JOINT_MAX_ACCEL[4] = inData.substring(idxAccelJ5 + 1, idxSpeedJ6).toFloat();
|
|
JOINT_MAX_SPEED[5] = inData.substring(idxSpeedJ6 + 1, idxAccelJ6).toFloat();
|
|
JOINT_MAX_ACCEL[5] = inData.substring(idxAccelJ6 + 1).toFloat();
|
|
}
|
|
|
|
void calibrateJoints(int* calJoints)
|
|
{
|
|
// check which joints to calibrate
|
|
bool calAllDone = false;
|
|
bool calJointsDone[NUM_JOINTS];
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
calJointsDone[i] = !calJoints[i];
|
|
}
|
|
|
|
// first pass of calibration, fast speed
|
|
for (int i = 0; i < NUM_JOINTS; i++)
|
|
{
|
|
stepperJoints[i].setSpeed(CAL_SPEED * CAL_SPEED_MULT[i] * CAL_DIR[i]);
|
|
}
|
|
while (!calAllDone)
|
|
{
|
|
calAllDone = true;
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
// if joint is not calibrated yet
|
|
if (!calJointsDone[i])
|
|
{
|
|
// check limit switches
|
|
if (!reachedLimitSwitch(i))
|
|
{
|
|
// limit switch not reached, continue moving
|
|
stepperJoints[i].runSpeed();
|
|
calAllDone = false;
|
|
}
|
|
else
|
|
{
|
|
// limit switch reached
|
|
stepperJoints[i].setSpeed(0); // redundancy
|
|
calJointsDone[i] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
delay(2000);
|
|
|
|
return;
|
|
}
|
|
|
|
bool reachedLimitSwitch(int joint)
|
|
{
|
|
int pin = CAL_PINS[joint];
|
|
// check multiple times to deal with noise
|
|
// possibly EMI from motor cables?
|
|
if (digitalRead(pin) == LIMIT_SWITCH_HIGH[joint])
|
|
{
|
|
if (digitalRead(pin) == LIMIT_SWITCH_HIGH[joint])
|
|
{
|
|
if (digitalRead(pin) == LIMIT_SWITCH_HIGH[joint])
|
|
{
|
|
if (digitalRead(pin) == LIMIT_SWITCH_HIGH[joint])
|
|
{
|
|
if (digitalRead(pin) == LIMIT_SWITCH_HIGH[joint])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void stateTRAJ()
|
|
{
|
|
// initialise joint steps
|
|
int curEncSteps[NUM_JOINTS];
|
|
readEncPos(curEncSteps);
|
|
|
|
int cmdEncSteps[NUM_JOINTS];
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
cmdEncSteps[i] = curEncSteps[i];
|
|
}
|
|
|
|
// initialise AccelStepper instance
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
stepperJoints[i] = AccelStepper(1, STEP_PINS[i], DIR_PINS[i]);
|
|
stepperJoints[i].setPinsInverted(true, false, false); // DM542T CW
|
|
stepperJoints[i].setAcceleration(MOTOR_MAX_ACCEL[i]);
|
|
stepperJoints[i].setMaxSpeed(MOTOR_MAX_SPEED[i]);
|
|
}
|
|
stepperJoints[3].setPinsInverted(false, false, false); // J4 DM320T CCW
|
|
stepperJoints[3].setMinPulseWidth(7.5);
|
|
|
|
// message
|
|
String inData = "";
|
|
|
|
// start loop
|
|
while (STATE == STATE_TRAJ)
|
|
{
|
|
char received = '\0';
|
|
// check for message from host
|
|
if (Serial.available())
|
|
{
|
|
received = Serial.read();
|
|
inData += received;
|
|
}
|
|
|
|
// process message when new line character is received
|
|
if (received == '\n')
|
|
{
|
|
String function = inData.substring(0, 2);
|
|
// update trajectory information
|
|
if (function == "MT")
|
|
{
|
|
// read current joint positions
|
|
readEncPos(curEncSteps);
|
|
|
|
// update host with joint positions
|
|
String msg = String("JP") + String("A") + String(curEncSteps[0]) + String("B") + String(curEncSteps[1]) + String("C") + String(curEncSteps[2])
|
|
+ String("D") + String(curEncSteps[3]) + String("E") + String(curEncSteps[4]) + String("F") + String(curEncSteps[5]) + String("\n");
|
|
Serial.print(msg);
|
|
|
|
// get new position commands
|
|
int msgIdxJ1 = inData.indexOf('A');
|
|
int msgIdxJ2 = inData.indexOf('B');
|
|
int msgIdxJ3 = inData.indexOf('C');
|
|
int msgIdxJ4 = inData.indexOf('D');
|
|
int msgIdxJ5 = inData.indexOf('E');
|
|
int msgIdxJ6 = inData.indexOf('F');
|
|
cmdEncSteps[0] = inData.substring(msgIdxJ1 + 1, msgIdxJ2).toInt();
|
|
cmdEncSteps[1] = inData.substring(msgIdxJ2 + 1, msgIdxJ3).toInt();
|
|
cmdEncSteps[2] = inData.substring(msgIdxJ3 + 1, msgIdxJ4).toInt();
|
|
cmdEncSteps[3] = inData.substring(msgIdxJ4 + 1, msgIdxJ5).toInt();
|
|
cmdEncSteps[4] = inData.substring(msgIdxJ5 + 1, msgIdxJ6).toInt();
|
|
cmdEncSteps[5] = inData.substring(msgIdxJ6 + 1).toInt();
|
|
|
|
// update target joint positions
|
|
readEncPos(curEncSteps);
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
//curEncSteps[1] = J2encPos.read() * ENC_DIR[1];
|
|
int diffEncSteps = cmdEncSteps[i] - curEncSteps[i];
|
|
//if (abs(diffEncSteps) > 2)
|
|
//{
|
|
int diffMotSteps = diffEncSteps / ENC_MULT[i];
|
|
/*
|
|
if (diffMotSteps < MOTOR_STEPS_PER_REV[i])
|
|
{
|
|
// for the last rev of motor, introduce artificial decceleration
|
|
// to help prevent overshoot
|
|
diffMotSteps = diffMotSteps / 2;
|
|
}
|
|
*/
|
|
//stepperJoints[i].move(diffMotSteps);
|
|
stepperJoints[i].moveTo(cmdEncSteps[i]);
|
|
stepperJoints[i].run();
|
|
//}
|
|
}
|
|
}
|
|
else if (function == "JC")
|
|
{
|
|
// calibrate joint 6
|
|
int calJoint6[] = { 0, 0, 0, 0, 0, 1 }; // 000001
|
|
calibrateJoints(calJoint6);
|
|
|
|
// record encoder steps
|
|
int calStepJ6 = J6encPos.read() * ENC_DIR[5];
|
|
|
|
// calibrate joints 1 to 5
|
|
int calJoints[] = { 1, 1, 1, 1, 1, 0 }; // 111110
|
|
calibrateJoints(calJoints);
|
|
|
|
// record encoder steps
|
|
int calStepJ1 = J1encPos.read() * ENC_DIR[0];
|
|
int calStepJ2 = J2encPos.read() * ENC_DIR[1];
|
|
int calStepJ3 = J3encPos.read() * ENC_DIR[2];
|
|
int calStepJ4 = J4encPos.read() * ENC_DIR[3];
|
|
int calStepJ5 = J5encPos.read() * ENC_DIR[4];
|
|
|
|
// if limit switch at lower end, set encoder to 0
|
|
// otherwise set to encoder upper limit
|
|
J1encPos.write(0);
|
|
J2encPos.write(0);
|
|
J3encPos.write(ENC_RANGE_STEPS[2]);
|
|
J4encPos.write(0);
|
|
J5encPos.write(0);
|
|
J6encPos.write(ENC_RANGE_STEPS[5]);
|
|
|
|
// read current joint positions
|
|
readEncPos(curEncSteps);
|
|
|
|
// return to original position
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
stepperJoints[i].setAcceleration(MOTOR_MAX_ACCEL[i]);
|
|
stepperJoints[i].setMaxSpeed(MOTOR_MAX_SPEED[i]);
|
|
cmdEncSteps[i] = REST_ENC_POSITIONS[i];
|
|
stepperJoints[i].move((REST_ENC_POSITIONS[i] - curEncSteps[i]) / ENC_MULT[i]);
|
|
}
|
|
|
|
bool restPosReached = false;
|
|
while (!restPosReached)
|
|
{
|
|
restPosReached = true;
|
|
// read current joint positions
|
|
readEncPos(curEncSteps);
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
if (abs(REST_ENC_POSITIONS[i] - curEncSteps[i]) > 5)
|
|
{
|
|
restPosReached = false;
|
|
stepperJoints[i].move((REST_ENC_POSITIONS[i] - curEncSteps[i]) / ENC_MULT[i]);
|
|
stepperJoints[i].run();
|
|
}
|
|
}
|
|
}
|
|
|
|
// calibration done, send calibration values
|
|
String msg = String("JC") + String("A") + String(calStepJ1) + String("B") + String(calStepJ2) + String("C") + String(calStepJ3)
|
|
+ String("D") + String(calStepJ4) + String("E") + String(calStepJ5) + String("F") + String(calStepJ6) + String("\n");
|
|
Serial.print(msg);
|
|
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
stepperJoints[i].setAcceleration(MOTOR_MAX_ACCEL[i]);
|
|
stepperJoints[i].setMaxSpeed(MOTOR_MAX_SPEED[i]);
|
|
}
|
|
}
|
|
else if (function == "JP")
|
|
{
|
|
// read current joint positions
|
|
readEncPos(curEncSteps);
|
|
|
|
// update host with joint positions
|
|
String msg = String("JP") + String("A") + String(curEncSteps[0]) + String("B") + String(curEncSteps[1]) + String("C") + String(curEncSteps[2])
|
|
+ String("D") + String(curEncSteps[3]) + String("E") + String(curEncSteps[4]) + String("F") + String(curEncSteps[5]) + String("\n");
|
|
Serial.print(msg);
|
|
}
|
|
else if (function == "SS")
|
|
{
|
|
updateStepperSpeed(inData);
|
|
// set motor speed and acceleration
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
MOTOR_MAX_SPEED[i] = JOINT_MAX_SPEED[i] * ENC_STEPS_PER_DEG[i] / ENC_MULT[i];
|
|
MOTOR_MAX_ACCEL[i] = JOINT_MAX_ACCEL[i] * ENC_STEPS_PER_DEG[i] / ENC_MULT[i];
|
|
stepperJoints[i].setAcceleration(MOTOR_MAX_ACCEL[i] * MOTOR_ACCEL_MULT[i]);
|
|
stepperJoints[i].setMaxSpeed(MOTOR_MAX_SPEED[i] * MOTOR_SPEED_MULT[i]);
|
|
}
|
|
// read current joint positions
|
|
readEncPos(curEncSteps);
|
|
|
|
// update host with joint positions
|
|
String msg = String("JP") + String("A") + String(curEncSteps[0]) + String("B") + String(curEncSteps[1]) + String("C") + String(curEncSteps[2])
|
|
+ String("D") + String(curEncSteps[3]) + String("E") + String(curEncSteps[4]) + String("F") + String(curEncSteps[5]) + String("\n");
|
|
Serial.print(msg);
|
|
}
|
|
else if (function == "ST")
|
|
{
|
|
if (!initStateTraj(inData))
|
|
{
|
|
STATE = STATE_INIT;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// clear message
|
|
inData = "";
|
|
}
|
|
// execute motor commands
|
|
for (int i = 0; i < NUM_JOINTS; ++i)
|
|
{
|
|
// target joint positions are already updated, just call run()
|
|
stepperJoints[i].run();
|
|
}
|
|
}
|
|
}
|
|
|
|
void stateINIT()
|
|
{
|
|
// message
|
|
String inData = "";
|
|
|
|
// start loop
|
|
while (STATE == STATE_INIT)
|
|
{
|
|
char received = '\0';
|
|
// check for message from host
|
|
if (Serial.available())
|
|
{
|
|
received = Serial.read();
|
|
inData += received;
|
|
}
|
|
|
|
// process message when new line character is received
|
|
if (received == '\n')
|
|
{
|
|
String function = inData.substring(0, 2);
|
|
// update trajectory information
|
|
if (function == "ST")
|
|
{
|
|
if (initStateTraj(inData))
|
|
{
|
|
STATE = STATE_TRAJ;
|
|
return;
|
|
}
|
|
}
|
|
inData = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
void stateERR()
|
|
{
|
|
// enter holding state
|
|
digitalWrite(J1stepPin, LOW);
|
|
digitalWrite(J2stepPin, LOW);
|
|
digitalWrite(J3stepPin, LOW);
|
|
digitalWrite(J4stepPin, LOW);
|
|
digitalWrite(J5stepPin, LOW);
|
|
digitalWrite(J6stepPin, LOW);
|
|
|
|
// do recovery @TODO
|
|
while (STATE == STATE_ERR) {}
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
// state control
|
|
switch (STATE)
|
|
{
|
|
case STATE_TRAJ:
|
|
stateTRAJ();
|
|
break;
|
|
case STATE_ERR:
|
|
stateERR();
|
|
break;
|
|
default:
|
|
stateINIT();
|
|
break;
|
|
}
|
|
}
|