demo project
Dependencies: AX-12A Dynamixel mbed iothub_client EthernetInterface NTPClient ConfigFile SDFileSystem iothub_amqp_transport mbed-rtos proton-c-mbed wolfSSL
ArmController.cpp
- Committer:
- henryrawas
- Date:
- 2015-12-29
- Revision:
- 7:6723f6887d00
- Child:
- 8:d98e2dec0f40
File content as of revision 7:6723f6887d00:
#include "mbed.h" #include "rtos.h" #include "EthernetInterface.h" #include "mbed/logging.h" #include "mbed/mbedtime.h" #include <NTPClient.h> #include <DynamixelBus.h> #include <AX12.h> #include <Terminal.h> #include <vector> #include <RobotArm.h> #include <MeasureBuf.h> #include <IothubRobotArm.h> #include <ActionBuf.h> #include <Sequences.h> using namespace std; void PushMeasurements(MeasureGroup measureGroup, int partSize, RobotArm robotArm) { vector<float> lastVals; time_t seconds = time(NULL); robotArm.GetArmMeasure(NM_Temperature, lastVals); printf( "Temperatures: "); for( int servoIndex = 0; servoIndex < partSize; servoIndex++ ) { printf( "%d:%f ", servoIndex, lastVals[servoIndex]); } printf( "\r\n"); measureGroup.SetMeasure(NM_Temperature, seconds, lastVals); MeasureBuf.push(measureGroup); robotArm.GetArmMeasure(NM_Voltage, lastVals); printf( "Voltage: "); for( int servoIndex = 0; servoIndex < partSize; servoIndex++ ) { printf( "%d:%f ", servoIndex, lastVals[servoIndex]); } printf( "\r\n"); measureGroup.SetMeasure(NM_Voltage, seconds, lastVals); MeasureBuf.push(measureGroup); robotArm.GetArmMeasure(NM_Degrees, lastVals); printf( "Rotation: "); for( int servoIndex = 0; servoIndex < partSize; servoIndex++ ) { printf( "%d:%f ", servoIndex, lastVals[servoIndex]); } printf( "\r\n"); measureGroup.SetMeasure(NM_Degrees, seconds, lastVals); MeasureBuf.push(measureGroup); } void PushAlert(int severity, char* msg, char* atype) { Alert alert; time_t seconds = time(NULL); alert.SetAlert(severity, seconds, msg, atype); AlertBuf.push(alert); } void PushPositionAlert(int severity, int partIx, float pos) { Alert alert; time_t seconds = time(NULL); alert.SetPositionAlert(severity, seconds, partIx, pos); AlertBuf.push(alert); } vector<float> initPositions; enum MainStates { MS_Idle = 0x0, MS_Running = 0x1, MS_Paused = 0x2, MS_Stopping = 0x3, MS_Error = 0x4, MS_CancelOne = 0x5, MS_CancelAll = 0x6, MS_CancelToM = 0x7 }; Queue<vector<ActionSequence>, 16> SequenceQ; volatile MainStates MainState; bool RunInSequence; bool RunInMoveStep; bool RunInDelay; void* CancelToMatch; osThreadId mainTid; void ControlArm(const char* cmd) { if (strncmp(cmd, "pause", 5) == 0) { printf( "Pause cmd\r\n"); MainState = MS_Paused; osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "resume", 6) == 0) { printf( "Resume cmd\r\n"); MainState = MS_Running; osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "runupdown", 9) == 0) { printf( "Runupdown cmd\r\n"); MainState = MS_CancelToM; CancelToMatch = &UpDownSeq; SequenceQ.put(&UpDownSeq); osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "runuptwist", 10) == 0) { printf( "Runuptwist cmd\r\n"); MainState = MS_CancelToM; CancelToMatch = &UpTwistSeq; SequenceQ.put(&UpTwistSeq); osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "runhome", 10) == 0) { printf( "Runhome cmd\r\n"); MainState = MS_CancelToM; CancelToMatch = &StartSeq; SequenceQ.put(&StartSeq); osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "runwave", 10) == 0) { printf( "Runwave cmd\r\n"); MainState = MS_CancelToM; CancelToMatch = &WaveSeq; SequenceQ.put(&WaveSeq); osSignalSet(mainTid, AS_Action); } else if (strncmp(cmd, "cancelone", 9) == 0) { printf( "CancelOne cmd\r\n"); MainState = MS_CancelOne; osSignalSet(mainTid, AS_Action); } } // run sequence thread timer routine void NextSeq(void const * tid) { RunInDelay = false; osSignalSet((osThreadId)tid, AS_Action); } void RunController() { // init robot arm RobotArm robotArm; int partSize = robotArm.GetNumParts(); // set running state MainState = MS_Idle; RunInSequence = false; RunInMoveStep = false; RunInDelay = false; // get initial positions MeasureGroup measureGroup; robotArm.GetArmPositions(initPositions); vector<float> lastVals; // do inital status report PushMeasurements(measureGroup, partSize, robotArm); SendIothubData(); // Prepare main thread mainTid = osThreadGetId(); int32_t signals = AS_Action; // create sequences MakeSequences(partSize, initPositions); // add to queue SequenceQ.put(&StartSeq); // state for sequence vector<ActionSequence> *curseq = NULL; int curseqIx = 0; // signal to run the default action for demo osSignalSet(mainTid, AS_Action); RtosTimer delayTimer(NextSeq, osTimerOnce, (void *)osThreadGetId()); MainState = MS_Running; while( true ) { osEvent mainEvent = osSignalWait(signals, osWaitForever); switch (MainState) { case MS_Idle: break; case MS_Paused: printf( "Paused\r\n"); break; case MS_Stopping: printf( "Stopping\r\n"); break; case MS_Error: printf( "Error\r\n"); break; case MS_CancelOne: printf( "Cancel sequence\r\n"); RunInSequence = false; RunInMoveStep = false; if (RunInDelay) { RunInDelay = false; delayTimer.stop(); } MainState = MS_Running; osSignalSet(mainTid, AS_Action); break; case MS_CancelAll: RunInSequence = false; RunInMoveStep = false; if (RunInDelay) { RunInDelay = false; delayTimer.stop(); } while (1) { osEvent evt = SequenceQ.get(0); if (evt.status != osEventMessage) break; } MainState = MS_Running; break; case MS_CancelToM: RunInSequence = false; RunInMoveStep = false; if (RunInDelay) { RunInDelay = false; delayTimer.stop(); } while (1) { osEvent evt = SequenceQ.get(0); if (evt.status != osEventMessage) break; else if (evt.value.p == CancelToMatch) { curseq = (vector<ActionSequence> *)evt.value.p; curseqIx = 0; RunInSequence = true; } } MainState = MS_Running; osSignalSet(mainTid, AS_Action); break; case MS_Running: if (RunInDelay) { // waiting for timer to fire. do nothing break; } if (!RunInSequence) { osEvent evt = SequenceQ.get(0); if (evt.status == osEventMessage) { printf( "New Seq \r\n"); curseq = (vector<ActionSequence> *)evt.value.p; curseqIx = 0; RunInSequence = true; RunInMoveStep = false; } } if (RunInSequence) { if (RunInMoveStep) { if (!robotArm.MoveArmPositionTest()) { // report position error int ix = robotArm.GetLastErrorPart(); float diff = robotArm.GetLastPosDiff(); printf( "Position error detected part %d, diff %f \r\n", ix, diff); PushPositionAlert(AS_Error, ix, diff); MainState = MS_Error; SendIothubData(); break; } if (robotArm.MoveArmPositionsHasNext()) { //printf( "Next Step\r\n"); int delaystep = 0; bool ok = robotArm.MoveArmPositionsNext(); if (ok) { robotArm.MoveArmPositionsDelay(delaystep); if (delaystep > 0) { RunInDelay = true; delayTimer.start(delaystep); } else { osSignalSet(mainTid, AS_Action); } } else { // report HW error // int partix = robotArm.GetLastErrorPart(); // int errCode = robotArm.GetLastError(); // send alert MainState = MS_Error; } } else { printf( "No more Step\r\n"); RunInMoveStep = false; } } if (!RunInMoveStep) { printf( "Next Seq %d\r\n", curseqIx); if (curseq != NULL) { if (curseqIx >= curseq->size()) { RunInSequence = false; break; } ActionSequence aseq = (*curseq)[curseqIx]; curseqIx++; bool ok; switch (aseq.ActionType) { case SA_SetGoal: printf( " - Move arm start\r\n"); ok = robotArm.MoveArmPositionsStart(aseq.GoalVals, aseq.Ms); if (ok) { RunInMoveStep = true; osSignalSet(mainTid, AS_Action); } else { // TODO: send alert } break; case SA_Delay: printf( " - Delay\r\n"); RunInDelay = true; delayTimer.start(aseq.Ms); break; case SA_Status: printf( " - Status\r\n"); robotArm.GetArmPositions(lastVals); PushMeasurements(measureGroup, partSize, robotArm); SendIothubData(); osSignalSet(mainTid, AS_Action); break; case SA_Repeat: printf( " - Repeat\r\n"); curseqIx = 0; osSignalSet(mainTid, AS_Action); break; } } } } break; } } }