MCP with wheel

Dependencies:   mbed-dev_spine

Revision:
11:58a70b97c750
Parent:
10:54e95428798b
Child:
12:2aa99d54af80
diff -r 54e95428798b -r 58a70b97c750 main.cpp
--- a/main.cpp	Thu Jun 04 01:26:01 2020 +0000
+++ b/main.cpp	Mon Oct 19 23:29:46 2020 +0000
@@ -28,7 +28,10 @@
  #define KD_MAX 5.0f
  #define T_MIN -18.0f
  #define T_MAX 18.0f
- 
+ #define P_GAIN_MIN 0.0f
+ #define P_GAIN_MAX 2048.0f
+ #define I_GAIN_MIN 0.0f
+ #define I_GAIN_MAX 2048.0f
  /// Joint Soft Stops ///
  #define A_LIM_P 1.5f
  #define A_LIM_N -1.5f
@@ -132,6 +135,19 @@
      msg->data[6] = ((kd_int&0xF)<<4)|(t_int>>8);
      msg->data[7] = t_int&0xff;
      }
+
+void pack_cmd2(CANMessage * msg, joint_control joint){
+     
+     /// limit data to be within bounds ///
+     float v_des = fminf(fmaxf(V_MIN, joint.v_des), V_MAX);
+     /// pack ints into the can buffer ///
+     uint16_t kp = (uint16_t)(fminf(fmaxf(P_GAIN_MIN, joint.kp), P_GAIN_MAX) * 32);
+     uint16_t ki = (uint16_t)(fminf(fmaxf(I_GAIN_MIN, joint.kd), I_GAIN_MAX) * 32);
+     
+     memcpy(msg->data, &v_des, 4);
+     memcpy(msg->data + 4, &kp, 2);
+     memcpy(msg->data + 6, &ki, 2);
+     }
      
 /// CAN Reply Packet Structure ///
 /// 16 bit position, between -4*pi and 4*pi
@@ -147,31 +163,38 @@
 
 void unpack_reply(CANMessage msg, leg_state * leg){
     /// unpack ints from can buffer ///
-    uint16_t id = msg.data[0];
-    uint16_t p_int = (msg.data[1]<<8)|msg.data[2];
-    uint16_t v_int = (msg.data[3]<<4)|(msg.data[4]>>4);
-    uint16_t i_int = ((msg.data[4]&0xF)<<8)|msg.data[5];
-    /// convert uints to floats ///
-    float p = uint_to_float(p_int, P_MIN, P_MAX, 16);
-    float v = uint_to_float(v_int, V_MIN, V_MAX, 12);
-    float t = uint_to_float(i_int, -T_MAX, T_MAX, 12);
-    
-    if(id==1){
-        leg->a.p = p;
-        leg->a.v = v;
-        leg->a.t = t;
+    if(msg.id == 6) {
+        float p, v;
+        memcpy(&v, msg.data, 4);
+        memcpy(&p, msg.data + 4, 4);
+        leg->k.v = v;
+        leg->k.p = p;
+        leg->k.t = 0.0f;
+    } else {
+        uint16_t id = msg.data[0];
+        uint16_t p_int = (msg.data[1]<<8)|msg.data[2];
+        uint16_t v_int = (msg.data[3]<<4)|(msg.data[4]>>4);
+        uint16_t i_int = ((msg.data[4]&0xF)<<8)|msg.data[5];
+        /// convert uints to floats ///
+        float p = uint_to_float(p_int, P_MIN, P_MAX, 16);
+        float v = uint_to_float(v_int, V_MIN, V_MAX, 12);
+        float t = uint_to_float(i_int, -T_MAX, T_MAX, 12);
+
+        if(id == 1) {
+            leg->a.p = p;
+            leg->a.v = v;
+            leg->a.t = t;
+        } else if(id == 2) {
+            leg->h.p = p;
+            leg->h.v = v;
+            leg->h.t = t;
+        } else if(id == 3) {
+            leg->k.p = p;
+            leg->k.v = v;
+            leg->k.t = t;
         }
-    else if(id==2){
-        leg->h.p = p;
-        leg->h.v = v;
-        leg->h.t = t;
-        }
-    else if(id==3){
-        leg->k.p = p;
-        leg->k.v = v;
-        leg->k.t = t;
-        }
-    } 
+    }
+} 
 
  void rxISR1() {
     can1.read(rxMsg1);                    // read message into Rx message storage
@@ -182,20 +205,22 @@
     unpack_reply(rxMsg2, &l2_state);
     }
 void PackAll(){
-    pack_cmd(&a1_can, l1_control.a); 
-    pack_cmd(&a2_can, l2_control.a); 
+//    pack_cmd(&a1_can, l1_control.a); 
+//    pack_cmd(&a2_can, l2_control.a); 
     pack_cmd(&h1_can, l1_control.h); 
     pack_cmd(&h2_can, l2_control.h); 
-    pack_cmd(&k1_can, l1_control.k); 
-    pack_cmd(&k2_can, l2_control.k); 
+    pack_cmd2(&k1_can, l1_control.k); 
+    pack_cmd2(&k2_can, l2_control.k); 
     
     }
 void WriteAll(){
     //toggle = 1;
+/*
     can1.write(a1_can);
     wait(.00002);
     can2.write(a2_can);
     wait(.00002);
+*/
     can1.write(h1_can);
     wait(.00002);
     can2.write(h2_can);
@@ -251,7 +276,7 @@
     msg->data[5] = 0xFF;
     msg->data[6] = 0xFF;
     msg->data[7] = 0xFE;
-    WriteAll();
+    //WriteAll();
     }
 
 void EnterMotorMode(CANMessage * msg){
@@ -265,6 +290,18 @@
     msg->data[7] = 0xFC;
     //WriteAll();
     }
+
+void EnterVelCtrlMode(CANMessage * msg){
+    msg->data[0] = 0xFF;
+    msg->data[1] = 0xFF;
+    msg->data[2] = 0xFF;
+    msg->data[3] = 0xFF;
+    msg->data[4] = 0xFF;
+    msg->data[5] = 0xFF;
+    msg->data[6] = 0xFF;
+    msg->data[7] = 0xFB;
+    //WriteAll();
+    }
     
 void ExitMotorMode(CANMessage * msg){
     msg->data[0] = 0xFF;
@@ -277,6 +314,7 @@
     msg->data[7] = 0xFD;
     //WriteAll();
     }
+
 void serial_isr(){
      /// handle keyboard commands from the serial terminal ///
      while(pc.readable()){
@@ -286,24 +324,26 @@
             case(27):
                 //loop.detach();
                 printf("\n\r exiting motor mode \n\r");
-                ExitMotorMode(&a1_can);
-                ExitMotorMode(&a2_can);
+//                ExitMotorMode(&a1_can);
+//                ExitMotorMode(&a2_can);
                 ExitMotorMode(&h1_can);
                 ExitMotorMode(&h2_can);
                 ExitMotorMode(&k1_can);
                 ExitMotorMode(&k2_can);
+                l1_control.k.v_des = 0.0f;
+                l2_control.k.v_des = 0.0f;
                 enabled = 0;
                 break;
             case('m'):
                 printf("\n\r entering motor mode \n\r");
-                EnterMotorMode(&a1_can);
-                EnterMotorMode(&a2_can);
+//                EnterMotorMode(&a1_can);
+//                EnterMotorMode(&a2_can);
                 EnterMotorMode(&h1_can);
                 EnterMotorMode(&h2_can);
-                EnterMotorMode(&k1_can);
-                EnterMotorMode(&k2_can);
+                EnterVelCtrlMode(&k1_can);
+                EnterVelCtrlMode(&k2_can);
                 wait(.5);
-                enabled = 1;
+                enabled = 0xC;
                 //loop.attach(&sendCMD, .001);
                 break;
             case('s'):
@@ -314,12 +354,32 @@
                 break;
             case('z'):
                 printf("\n\r zeroing \n\r");
-                Zero(&a1_can);
-                Zero(&a2_can);
+//                Zero(&a1_can);
+//                Zero(&a2_can);
+                Zero(&h1_can);
+                Zero(&h2_can);
+                l1_control.k.v_des = 0.0f;
+                l2_control.k.v_des = 0.0f;
+                pack_cmd2(&k1_can, l1_control.k);
+                pack_cmd2(&k2_can, l2_control.k);
+                break;
+            case('+'):
+                printf("+");
                 Zero(&h1_can);
                 Zero(&h2_can);
-                Zero(&k1_can);
-                Zero(&k2_can);
+                l1_control.k.v_des += PI * 2.0f * 0.1f;
+                l2_control.k.v_des += PI * 2.0f * 0.1f;
+                pack_cmd2(&k1_can, l1_control.k);
+                pack_cmd2(&k2_can, l2_control.k);
+                break;
+            case('-'):
+                printf("-");
+                Zero(&h1_can);
+                Zero(&h2_can);
+                l1_control.k.v_des -= PI * 2.0f * 0.1f;
+                l2_control.k.v_des -= PI * 2.0f * 0.1f;
+                pack_cmd2(&k1_can, l1_control.k);
+                pack_cmd2(&k2_can, l2_control.k);
                 break;
             }
         }
@@ -370,7 +430,6 @@
     PackAll();
     WriteAll();
 
-
     //for (int i = 0; i<TX_LEN; i++) {
      //   tx_buff[i] = 2*rx_buff[i];
     //}
@@ -404,53 +463,74 @@
     
 void control()
 {
-    
-    if(((spi_command.flags[0]&0x1)==1)  && (enabled==0)){
-        enabled = 1;
-        EnterMotorMode(&a1_can);
-        can1.write(a1_can);
-        EnterMotorMode(&a2_can);
-        can2.write(a2_can);
-        EnterMotorMode(&k1_can);
-        can1.write(k1_can);
-        EnterMotorMode(&k2_can);
-        can2.write(k2_can);
+    int32_t en_flag = spi_command.flags[0];
+
+    if((en_flag&0x1) && !(enabled&0x1)) {
+        enabled |= 0x1;
         EnterMotorMode(&h1_can);
         can1.write(h1_can);
+    }
+
+    if((en_flag&0x2) && !(enabled&0x2)) {
+        enabled |= 0x2;
         EnterMotorMode(&h2_can);
         can2.write(h2_can);
-        printf("e\n\r");
-        return;
+        wait(.00002);
+    }
+
+    if((en_flag&0x4) && !(enabled&0x4)) {
+        enabled |= 0x4;
+        EnterVelCtrlMode(&k1_can);
+        can1.write(k1_can);
+        wait(.00002);
     }
-    else if((((spi_command.flags[0]&0x1))==0)  && (enabled==1)){
-         enabled = 0;
-        ExitMotorMode(&a1_can);
-        can1.write(a1_can);
-        ExitMotorMode(&a2_can);
-        can2.write(a2_can);
+
+    if((en_flag&0x8) && !(enabled&0x8)) {
+        enabled |= 0x8;
+        EnterVelCtrlMode(&k2_can);
+        can2.write(k2_can);
+        wait(.00002);
+    }
+
+    if(!(en_flag&0x1) && (enabled&0x1)) {
+        enabled &= ~0x1;
         ExitMotorMode(&h1_can);
         can1.write(h1_can);
+        wait(.00002);
+    }
+
+    if(!(en_flag&0x2) && (enabled&0x2)) {
+        enabled &= ~0x2;
         ExitMotorMode(&h2_can);
         can2.write(h2_can);
+        wait(.00002);
+    }
+
+    if(!(en_flag&0x4) && (enabled&0x4)) {
+        enabled &= ~0x4;
         ExitMotorMode(&k1_can);
         can1.write(k1_can);
+        wait(.00002);
+    }
+
+    if(!(en_flag&0x8) && (enabled&0x8)) {
+        enabled &= ~0x8;
         ExitMotorMode(&k2_can);
         can2.write(k2_can);
-        printf("x\n\r");
-        return;
-        }
-    
-    spi_data.q_abad[0] = l1_state.a.p;
+        wait(.00002);
+    }
+
+//    spi_data.q_abad[0] = l1_state.a.p;
     spi_data.q_hip[0] = l1_state.h.p;
     spi_data.q_knee[0] = l1_state.k.p;
-    spi_data.qd_abad[0] = l1_state.a.v;
+//    spi_data.qd_abad[0] = l1_state.a.v;
     spi_data.qd_hip[0] = l1_state.h.v;
     spi_data.qd_knee[0] = l1_state.k.v;
     
-    spi_data.q_abad[1] = l2_state.a.p;
+//    spi_data.q_abad[1] = l2_state.a.p;
     spi_data.q_hip[1] = l2_state.h.p;
     spi_data.q_knee[1] = l2_state.k.p;
-    spi_data.qd_abad[1] = l2_state.a.v;
+//    spi_data.qd_abad[1] = l2_state.a.v;
     spi_data.qd_hip[1] = l2_state.h.v;
     spi_data.qd_knee[1] = l2_state.k.v;
     
@@ -470,51 +550,51 @@
         
         memset(&l1_control, 0, sizeof(l1_control));
         memset(&l2_control, 0, sizeof(l2_control));
-        
-        l1_control.a.p_des = spi_command.q_des_abad[0];
-        l1_control.a.v_des  = spi_command.qd_des_abad[0];
-        l1_control.a.kp = spi_command.kp_abad[0];
-        l1_control.a.kd = spi_command.kd_abad[0];
-        l1_control.a.t_ff = spi_command.tau_abad_ff[0];
-        
+
+//        l1_control.a.p_des = spi_command.q_des_abad[0];
+//        l1_control.a.v_des  = spi_command.qd_des_abad[0];
+//        l1_control.a.kp = spi_command.kp_abad[0];
+//        l1_control.a.kd = spi_command.kd_abad[0];
+//        l1_control.a.t_ff = spi_command.tau_abad_ff[0];
+
         l1_control.h.p_des = spi_command.q_des_hip[0];
         l1_control.h.v_des  = spi_command.qd_des_hip[0];
         l1_control.h.kp = spi_command.kp_hip[0];
         l1_control.h.kd = spi_command.kd_hip[0];
         l1_control.h.t_ff = spi_command.tau_hip_ff[0];
-        
+
         l1_control.k.p_des = spi_command.q_des_knee[0];
         l1_control.k.v_des  = spi_command.qd_des_knee[0];
         l1_control.k.kp = spi_command.kp_knee[0];
         l1_control.k.kd = spi_command.kd_knee[0];
         l1_control.k.t_ff = spi_command.tau_knee_ff[0];
-        
-        l2_control.a.p_des = spi_command.q_des_abad[1];
-        l2_control.a.v_des  = spi_command.qd_des_abad[1];
-        l2_control.a.kp = spi_command.kp_abad[1];
-        l2_control.a.kd = spi_command.kd_abad[1];
-        l2_control.a.t_ff = spi_command.tau_abad_ff[1];
-        
+
+//        l2_control.a.p_des = spi_command.q_des_abad[1];
+//        l2_control.a.v_des  = spi_command.qd_des_abad[1];
+//        l2_control.a.kp = spi_command.kp_abad[1];
+//        l2_control.a.kd = spi_command.kd_abad[1];
+//        l2_control.a.t_ff = spi_command.tau_abad_ff[1];
+
         l2_control.h.p_des = spi_command.q_des_hip[1];
         l2_control.h.v_des  = spi_command.qd_des_hip[1];
         l2_control.h.kp = spi_command.kp_hip[1];
         l2_control.h.kd = spi_command.kd_hip[1];
         l2_control.h.t_ff = spi_command.tau_hip_ff[1];
-        
+
         l2_control.k.p_des = spi_command.q_des_knee[1];
         l2_control.k.v_des  = spi_command.qd_des_knee[1];
         l2_control.k.kp = spi_command.kp_knee[1];
         l2_control.k.kd = spi_command.kd_knee[1];
         l2_control.k.t_ff = spi_command.tau_knee_ff[1];
-        
-        
+
+
         spi_data.flags[0] = 0;
         spi_data.flags[1] = 0;
-        spi_data.flags[0] |= softstop_joint(l1_state.a, &l1_control.a, A_LIM_P, A_LIM_N);
-        spi_data.flags[0] |= (softstop_joint(l1_state.h, &l1_control.h, H_LIM_P, H_LIM_N))<<1;
+        //spi_data.flags[0] |= softstop_joint(l1_state.a, &l1_control.a, A_LIM_P, A_LIM_N);
+        //spi_data.flags[0] |= (softstop_joint(l1_state.h, &l1_control.h, H_LIM_P, H_LIM_N))<<1;
         //spi_data.flags[0] |= (softstop_joint(l1_state.k, &l1_control.k, K_LIM_P, K_LIM_N))<<2;
-        spi_data.flags[1] |= softstop_joint(l2_state.a, &l2_control.a, A_LIM_P, A_LIM_N);
-        spi_data.flags[1] |= (softstop_joint(l2_state.h, &l2_control.h, H_LIM_P, H_LIM_N))<<1;
+        //spi_data.flags[1] |= softstop_joint(l2_state.a, &l2_control.a, A_LIM_P, A_LIM_N);
+        //spi_data.flags[1] |= (softstop_joint(l2_state.h, &l2_control.h, H_LIM_P, H_LIM_N))<<1;
         //spi_data.flags[1] |= (softstop_joint(l2_state.k, &l2_control.k, K_LIM_P, K_LIM_N))<<2;
         
         //spi_data.flags[0] = 0xbeef;
@@ -524,7 +604,8 @@
 //    }
     spi_data.checksum = xor_checksum((uint32_t*)&spi_data,14);
     for(int i = 0; i < DATA_LEN; i++){
-        tx_buff[i] = ((uint16_t*)(&spi_data))[i];}
+        tx_buff[i] = ((uint16_t*)(&spi_data))[i];
+        }
     
 }
     
@@ -560,8 +641,7 @@
     cs.fall(&spi_isr);
     printf("done\n\r");
 }
-
-    
+ 
 int main() {
     wait(1);
     //led = 1;
@@ -575,10 +655,10 @@
 
     //can1.frequency(1000000);                     // set bit rate to 1Mbps
     //can1.attach(&rxISR1);                 // attach 'CAN receive-complete' interrupt handler
-    can1.filter(CAN_ID<<21, 0xFFE00004, CANStandard, 0); //set up can filter
+    can1.filter(0, 0x7F8, CANStandard, 0); //set up can filter
     //can2.frequency(1000000);                     // set bit rate to 1Mbps
     //can2.attach(&rxISR2);                 // attach 'CAN receive-complete' interrupt handler
-    can2.filter(CAN_ID<<21, 0xFFE00004, CANStandard, 0); //set up can filter
+    can2.filter(0, 0x7F8, CANStandard, 0); //set up can filter
     
     memset(&tx_buff, 0, TX_LEN * sizeof(uint16_t));
     memset(&spi_data, 0, sizeof(spi_data_t));
@@ -608,12 +688,12 @@
     k1_can.id = 0x3;
     k2_can.id = 0x3;     
 
-    pack_cmd(&a1_can, l1_control.a); 
-    pack_cmd(&a2_can, l2_control.a); 
+//    pack_cmd(&a1_can, l1_control.a); 
+//    pack_cmd(&a2_can, l2_control.a); 
     pack_cmd(&h1_can, l1_control.h); 
     pack_cmd(&h2_can, l2_control.h); 
-    pack_cmd(&k1_can, l1_control.k); 
-    pack_cmd(&k2_can, l2_control.k); 
+    pack_cmd2(&k1_can, l1_control.k); 
+    pack_cmd2(&k2_can, l2_control.k); 
     WriteAll();
 
 
@@ -633,6 +713,9 @@
         unpack_reply(rxMsg1, &l1_state);
         wait_us(10);
 
+        int32_t en_flag = spi_command.flags[0];
+        pc.printf("%1X", (en_flag&0xF));
+
 //        counter++;
 //        can1.read(rxMsg1);
 //        unpack_reply(rxMsg1, &l1_state);