Advertisement
Guest User

Quadruped Walking Code

a guest
Jan 4th, 2013
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.07 KB | None | 0 0
  1. // Written by Daniel Rodgers-Pryor, 2013
  2. // This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
  3.  
  4.  
  5. #include <Servo.h>
  6. #include <Serial.h>
  7.  
  8. /*
  9.  * Classes
  10.  */
  11.  
  12. class Joint {
  13.     private:
  14.     Servo servo;
  15.     int PercentageToAngle(unsigned int p) {
  16.                 if (orientation == -1) {
  17.                         p = 100 - p;
  18.                 };
  19.                
  20.         return (((int) ((p * (float) (maxAngle - minAngle)) / 100.0f)) + offset + minAngle);
  21.     };
  22.  
  23.  
  24.     public:
  25.         int minAngle, maxAngle, offset, orientation, maxSpeed;
  26.     int targetAngle, currentAngle;
  27.         float actuationSpeed;
  28.     Joint() {
  29.                 orientation = 1;
  30.                 minAngle = 10;
  31.                 maxAngle = 160;
  32.                 offset = 0;
  33.                 maxSpeed = 500;
  34.                
  35.                 actuationSpeed = 1.0f;
  36.                
  37.                 targetAngle = PercentageToAngle(0);
  38.                 currentAngle = PercentageToAngle(0);
  39.     };
  40.        
  41.         Joint& ServoPin(unsigned int servoPin){ servo.attach(servoPin); return *this; }
  42.         Joint& SetFlipped(){ orientation *= -1; return *this; }
  43.         Joint& Orientation(int x){ orientation = x; return *this; }
  44.         Joint& MinAngle(int x){ minAngle = x; return *this; }
  45.         Joint& MaxAngle(int x){ maxAngle = x; return *this; }
  46.         Joint& MaxSpeed(int x){ maxSpeed = x; return *this; }
  47.         Joint& Offset(int x){ offset = x; return *this; }
  48.    
  49.     void Extend(float _actuationSpeed = 1) {
  50.         targetAngle = PercentageToAngle(100);
  51.                 actuationSpeed = _actuationSpeed;
  52.     };
  53.         void Mid(float _actuationSpeed = 1) {
  54.         targetAngle = PercentageToAngle(50);
  55.                 actuationSpeed = _actuationSpeed;
  56.     };
  57.     void Retract(float _actuationSpeed = 1) {
  58.         targetAngle = PercentageToAngle(0);
  59.                 actuationSpeed = _actuationSpeed;
  60.     };
  61.    
  62.     void SetExtention(unsigned int extention, float _actuationSpeed = 1) {
  63.         targetAngle = PercentageToAngle(extention);
  64.                 actuationSpeed = _actuationSpeed;
  65.     };
  66.    
  67.     void Update(unsigned long timedelta) {
  68.                 currentAngle += (int) min((targetAngle - currentAngle), actuationSpeed * timedelta * maxSpeed / 1000.0f);
  69.         servo.write(currentAngle);
  70.     };
  71. };
  72.  
  73. class Leg {
  74.     public:
  75.     Joint hip, knee;
  76.        
  77.         Leg& HipPin(unsigned int servoPin){ hip.ServoPin(servoPin); return *this; }
  78.         Leg& KneePin(unsigned int servoPin){ knee.ServoPin(servoPin); return *this; }
  79.    
  80.     void Reach() {
  81.         knee.SetExtention(40);
  82.                 hip.Extend(0.7f);
  83.     };
  84.     void Curl() {
  85.         knee.Retract();
  86.     };
  87.         void Pull() {
  88.                 hip.Retract(0.7f);
  89.         }
  90.    
  91.     void SetPose(unsigned int hipExtention, unsigned int kneeExtention) {
  92.         hip.SetExtention(hipExtention);
  93.         knee.SetExtention(kneeExtention);
  94.     };
  95.    
  96.     void Update(unsigned long timedelta) {
  97.         hip.Update(timedelta);
  98.         knee.Update(timedelta);
  99.     };
  100. };
  101.  
  102.  
  103. class Bot {
  104.     public:
  105.     Leg legs[4];
  106.  
  107.         void Splay() {
  108.                 for(int l = 0; l < 4; l++) {
  109.                         legs[l].Reach();
  110.                 }
  111.     };
  112.     void Stand() {
  113.         for(int l = 0; l < 4; l++) {
  114.                         legs[l].Curl();
  115.                 }
  116.     };
  117.         void SetFlipped() {
  118.         for(int l = 0; l < 4; l++) {
  119.                         legs[l].hip.SetFlipped();
  120.                         legs[l].knee.SetFlipped();
  121.                 }
  122.     };
  123.        
  124.    
  125.     void Update(unsigned long timedelta) {
  126.         for(int l = 0; l < 4; l++) {
  127.             legs[l].Update(timedelta);
  128.         }
  129.     };
  130. };
  131.  
  132. /*
  133.  * Setup
  134.  */
  135.  
  136. Bot bot;
  137. unsigned long time, timedelta;
  138. long delayActions;
  139.  
  140.  
  141. int l, i;
  142. boolean pull;
  143.  
  144. void setup() {
  145.         Serial.begin(9600); // Allows the use of Serial.print() debug statements using a serial monitor
  146.        
  147.         // Assign pins tot he hips and knees of each leg - THESE NEED TO BE CHOSEN FOR YOUR CONFIGURATION (see commented code at the start of loop()).
  148.         bot.legs[0].HipPin(2).KneePin(9);
  149.         bot.legs[1].HipPin(10).KneePin(3);
  150.         bot.legs[2].HipPin(11).KneePin(5);
  151.         bot.legs[3].HipPin(6).KneePin(4);
  152.        
  153.        
  154.         // Set which hips are flipped aroud (this defines 'forward')
  155.         bot.legs[2].hip.SetFlipped();
  156.         bot.legs[3].hip.SetFlipped();
  157.        
  158.         // Limit hip motion (I needed to do this to avoid hitting the Aduino board - I'm going to look for a better mounting to avoid this).
  159.         for(int l = 0; l < 4; l++) {
  160.                 bot.legs[l].hip.minAngle = 50;
  161.                 bot.legs[l].hip.maxAngle = 130;
  162.         }
  163.        
  164.         // Initialise
  165.         time = millis();
  166.         delayActions = 0;
  167.        
  168.         l=0;
  169.         i=0;
  170.         pull = false;
  171. }
  172.  
  173. /*
  174.  * Body
  175.  */
  176.  
  177. void loop() {
  178.         /*
  179.         I used this code to work out which pins were assigned to which leg (I connected them randomly)
  180.        
  181.         bot.legs[0].hip.Extend();
  182.         bot.Update(2000);
  183.         delay(2000);
  184.        
  185.         bot.legs[1].hip.Extend();
  186.         bot.Update(2000);
  187.         delay(2000);
  188.        
  189.         bot.legs[2].hip.Extend();
  190.         bot.Update(2000);
  191.         delay(2000);
  192.        
  193.         bot.legs[3].hip.Extend();
  194.         bot.Update(2000);
  195.         delay(2000);
  196.        
  197.        
  198.         bot.legs[0].knee.Extend();
  199.         bot.Update(2000);
  200.         delay(2000);
  201.        
  202.         bot.legs[1].knee.Extend();
  203.         bot.Update(2000);
  204.         delay(2000);
  205.        
  206.         bot.legs[2].knee.Extend();
  207.         bot.Update(2000);
  208.         delay(2000);
  209.        
  210.         bot.legs[3].knee.Extend();
  211.         bot.Update(2000);
  212.         delay(2000);
  213.         */
  214.        
  215.        
  216.         // Change in time since the last loop
  217.         timedelta = millis() - time;
  218.         time = millis();
  219.        
  220.         // Count down until instructions are issued again
  221.         delayActions -= timedelta;
  222.         if (delayActions <= 0) // Skip issuing instructions if the delay timer is positive
  223.         {
  224.                 delayActions = 0; // Reset timer
  225.                
  226.                 // Issue instructions
  227.                 if (!pull) {
  228.                         bot.legs[(l)%4].Curl(); // Curl the knee
  229.                         pull = true; // Set the hip to pull the leg back on the next instruction loop
  230.                        
  231.                     bot.legs[(l+1)%4].Reach(); // Reach witht he next leg
  232.                
  233.                         delayActions += 100; // Wait 100ms before pulling the hip back
  234.                 } else {
  235.                         bot.legs[(l)%4].Pull(); // Pull the hip back
  236.                         pull = false;
  237.                        
  238.                         l++; // Move to the next leg
  239.                         delayActions += 400; // Wait 400ms before curling and reaching again.
  240.                 }
  241.         }
  242.        
  243.         bot.Update(timedelta); // Calculate desired positions and write to the IO pins
  244.        
  245.         delay(10);
  246. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement