demo project

Dependencies:   AX-12A Dynamixel mbed iothub_client EthernetInterface NTPClient ConfigFile SDFileSystem iothub_amqp_transport mbed-rtos proton-c-mbed wolfSSL

Revision:
7:6723f6887d00
Child:
8:d98e2dec0f40
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArmController.cpp	Tue Dec 29 23:31:28 2015 +0000
@@ -0,0 +1,410 @@
+#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;
+        }
+
+    }
+}
+