demo project

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

Revision:
18:224289104fc0
Parent:
15:4bd10f531cdc
Child:
19:2f0ec9ac1238
--- a/RobotArm.cpp	Fri Jan 22 01:35:07 2016 +0000
+++ b/RobotArm.cpp	Sat Jan 23 00:08:30 2016 +0000
@@ -1,21 +1,19 @@
 #include "mbed.h"
 #include "rtos.h"
 
-#include <DynamixelBus.h>
-#include <NodeAX12.h>
-//#include <NodeEmul.h>
-#include <Terminal.h>
 #include <vector>
-#include <RobotArm.h>
+
+#include "DynamixelBus.h"
+#include "NodeAX12.h"
+#include "NodeEmul.h"
+#include "RobotArm.h"
 
 using namespace std;
 
+// create the bus interface for this device
 DynamixelBus dynbus( PTC17, PTC16, D7, D6, 500000 );
 
 
-// set the id for each part in the chain, in order
-int PartIds[] = { 2, 3, 4, 6, 1 };
-
 // default to move every 25 ms
 #define StepPeriodMs        25
 
@@ -32,20 +30,38 @@
 #define MaxVoltLimit        13
 #define MinVoltLimit        10
 
+// should arm test for positions ?
+#define TestPositions       false
+
 
 RobotArm::RobotArm()
 {
     // build arm
     for (int ix = 0; ix < NUMJOINTS; ix++)
     {
-        NodeAX12* servo = new NodeAX12(&dynbus, PartIds[ix]);
-        //NodeEmul* servo = new NodeEmul(PartIds[i]);
-        servo->DoAction(NA_Init, 0.0f);
-        _armParts[ix] = dynamic_cast<RobotNode*>(servo);
+        NodePartType nt = ArmJoints[ix].JointType;
+        switch (nt)
+        {
+            case NT_AX12:
+                _armParts[ix] = dynamic_cast<RobotNode*>(new NodeAX12(&dynbus, ArmJoints[ix].JointId));
+                break;
+                
+            case NT_Emul:
+                _armParts[ix] = dynamic_cast<RobotNode*>(new NodeEmul(ArmJoints[ix].JointId));
+                break;
+                
+            default:
+                printf("Error! Unknown node type defined");
+                _armParts[ix] = NULL;
+                break;
+        }
+        
+        _armParts[ix]->DoAction(NA_Init, 0.0f);
     }
+    
     _numParts = NUMJOINTS;
 
-    numsteps = 0;
+    _numsteps = 0;
     _stepms = StepPeriodMs;             
 }
 
@@ -55,7 +71,7 @@
     for (int ix = 0; ix < _numParts; ix++)
     {
         _armParts[ix]->DoAction(NA_ClearError, 0.0f);
-        failms[ix] = 0;
+        _failms[ix] = 0;
     }
 }
 
@@ -66,33 +82,33 @@
 
     MoveArmPositionsEnd();
     
-    GetArmPositions(lastpos);
+    GetArmPositions(_lastpos);
     
-    numsteps = totms / _stepms;
-    if (numsteps == 0) numsteps = 1;
+    _numsteps = totms / _stepms;
+    if (_numsteps == 0) _numsteps = 1;
     
     for (int ix = 0; ix < _numParts; ix++)
     {
         if (positions[ix] > 0.0f)
         {
-            endgoals[ix] = positions[ix];
-            float difference = (positions[ix] - lastpos[ix]) / (float)numsteps;
-            differentials[ix] = difference;
+            _endgoals[ix] = positions[ix];
+            float difference = (positions[ix] - _lastpos[ix]) / (float)_numsteps;
+            _differentials[ix] = difference;
         }
         else
         {
             // negative goal. Treat as don't move
-            differentials[ix] = 0.0f;
+            _differentials[ix] = 0.0f;
         }
-        failms[ix] = 0;
+        _failms[ix] = 0;
     }
 
-    curstep = 1;
+    _curstep = 1;
     
-    delayms = _stepms;
+    _delayms = _stepms;
     
-    elapseTimer.start();
-    expDelay = (int)elapseTimer.read_ms() + delayms;
+    _elapseTimer.start();
+    _expDelay = (int)_elapseTimer.read_ms() + _delayms;
     
     return true;
 }
@@ -100,52 +116,52 @@
 // continue interrupted action
 bool RobotArm::MoveArmPositionsResume()
 {
-    if (curstep > numsteps)
+    if (_curstep > _numsteps)
     {
         // no more steps 
         MoveArmPositionsEnd();
         return true;
     }
-    GetArmPositions(lastpos);
+    GetArmPositions(_lastpos);
     
     // reset numsteps to be what was remaining
-    numsteps = numsteps - curstep + 1;
+    _numsteps = _numsteps - _curstep + 1;
     
     for (int ix = 0; ix < _numParts; ix++)
     {
-        if (endgoals[ix] > 0.0f)
+        if (_endgoals[ix] > 0.0f)
         {
-            float difference = (endgoals[ix] - lastpos[ix]) / (float)numsteps;
-            differentials[ix] = difference;
+            float difference = (_endgoals[ix] - _lastpos[ix]) / (float)_numsteps;
+            _differentials[ix] = difference;
         }
         else
         {
             // negative goal. Treat as don't move
-            differentials[ix] = 0.0f;
+            _differentials[ix] = 0.0f;
         }
-        failms[ix] = 0;
+        _failms[ix] = 0;
     }
 
-    curstep = 1;
+    _curstep = 1;
     
-    delayms = _stepms;
+    _delayms = _stepms;
     
-    elapseTimer.start();
-    expDelay = (int)elapseTimer.read_ms() + delayms;
+    _elapseTimer.start();
+    _expDelay = (int)_elapseTimer.read_ms() + _delayms;
     
     return true;
 }
 
 bool RobotArm::MoveArmPositionsHasNext()
 {
-    return (curstep <= numsteps);
+    return (_curstep <= _numsteps);
 }
 
 bool RobotArm::MoveArmPositionsNext()
 {
     _lastErrorPart = 0;
 
-    if (curstep > numsteps)
+    if (_curstep > _numsteps)
     {
         // no more steps 
         MoveArmPositionsEnd();
@@ -158,11 +174,11 @@
     {
         if (_armParts[ix]->HasAction(NA_Rotate))
         {
-            float goal = (curstep == numsteps || differentials[ix] == 0.0f) ?
-                            endgoals[ix] :  // last step - use actual goal
-                            (lastpos[ix] + (differentials[ix] * (float)curstep));
-            lastgoals[ix] = goal;
-            if (differentials[ix] != 0.0f)
+            float goal = (_curstep == _numsteps || _differentials[ix] == 0.0f) ?
+                            _endgoals[ix] :  // last step - use actual goal
+                            (_lastpos[ix] + (_differentials[ix] * (float)_curstep));
+            _lastgoals[ix] = goal;
+            if (_differentials[ix] != 0.0f)
             {
                 bool ok = _armParts[ix]->DoAction(NA_Rotate, goal);
                 if (!ok)
@@ -181,8 +197,8 @@
         return false;
     }
     
-    curstep++;
-    if (curstep > numsteps)
+    _curstep++;
+    if (_curstep > _numsteps)
     {
         MoveArmPositionsEnd();
     }
@@ -193,29 +209,29 @@
 // calculate actual delay until expDelay
 bool RobotArm::MoveArmPositionsDelay(int& nextdelay)
 {
-    if (curstep <= numsteps)
+    if (_curstep <= _numsteps)
     {
-        int elapsed = (int)elapseTimer.read_ms();
+        int elapsed = (int)_elapseTimer.read_ms();
     
-        if (elapsed <= expDelay)
+        if (elapsed <= _expDelay)
         {
-            if (expDelay - elapsed < delayms)
-                nextdelay = expDelay - elapsed;
+            if (_expDelay - elapsed < _delayms)
+                nextdelay = _expDelay - elapsed;
             else
-                nextdelay = delayms;
+                nextdelay = _delayms;
             // set next expected time by adding step delay
-            expDelay += delayms;
+            _expDelay += _delayms;
         }
         else
         {
-            nextdelay = delayms;
+            nextdelay = _delayms;
            // set next expected time to now plus step delay
-            expDelay = elapsed + delayms;
+            _expDelay = elapsed + _delayms;
         }
     }
     else
     {
-        nextdelay = delayms;
+        nextdelay = _delayms;
     }
     
     return true;
@@ -236,10 +252,10 @@
 
 bool RobotArm::MoveArmPositionsEnd()
 {
-    if (numsteps > 0)
+    if (_numsteps > 0)
     {
-        elapseTimer.stop();
-        numsteps = 0;
+        _elapseTimer.stop();
+        _numsteps = 0;
     }
     return true;
 }
@@ -281,40 +297,46 @@
             break;
             
         case NM_Degrees:
-            for (int ix = 0; ix < _numParts; ix++)
+            if (TestPositions)
             {
-                float val = curvals[ix];
-                if (val > 0.0f)
+                // positions will frequently be off while arm is moving
+                // logic checks if position is outside expected threshold for a period of time
+                // may get false positives if goal is changed frequently
+                for (int ix = 0; ix < _numParts; ix++)
                 {
-                    float diff = fabs(val  - lastgoals[ix]);
-                    if (diff > (fabs(differentials[ix] * 2.0f) + PositionErrorAllow))
+                    float val = curvals[ix];
+                    if (val > 0.0f)
                     {
-                        int elapsed = (int)elapseTimer.read_ms();
-                        if (failms[ix] > 0)
+                        float diff = fabs(val  - _lastgoals[ix]);
+                        if (diff > (fabs(_differentials[ix] * 2.0f) + PositionErrorAllow))
                         {
-                            if (elapsed - failms[ix] > FailMsLimit)
+                            int elapsed = (int)_elapseTimer.read_ms();
+                            if (_failms[ix] > 0)
                             {
-                                // continuous failure for time period
-                                // report failure
-                                _lastPosDiff = diff;
-                                _lastErrorPart = ix;
-        
-                                failms[ix] = 0;
-                                rc = -1;
+                                if (elapsed - _failms[ix] > FailMsLimit)
+                                {
+                                    // continuous failure for time period
+                                    // report failure
+                                    _lastPosDiff = diff;
+                                    _lastErrorPart = ix;
+            
+                                    _failms[ix] = 0;
+                                    rc = -1;
+                                }
+                            }
+                            else
+                            {
+                                // first failure after success
+                                // remember first fail time.
+                                _failms[ix] = elapsed;
                             }
                         }
                         else
                         {
-                            // first failure after success
-                            // remember first fail time.
-                            failms[ix] = elapsed;
+                            // within allowable range - clear time
+                            _failms[ix] = 0;
                         }
                     }
-                    else
-                    {
-                        // within allowable range - clear time
-                        failms[ix] = 0;
-                    }
                 }
             }
             break;