Arduino to Generate GAIT cycl patters using CubeMars actuators

Hello All,

I am new to the Arduino environment, I need help in developing logic to run my Cube Mars Actuator (Based on MIT Mini Cheetah Project) to run GAIT cycle pattern as per the data input from my end,
I am sharing a screenshot below for reference.
I am communicating with the actuator using CAN bus shield.


I can share mode details about the project if needed, feel free to reach out to me anytime.

Okey. Help with what?
Please read and use this link to know what forum would You to post: How to get the best out of this forum - Using Arduino / IDE 1.x - Arduino Forum

Hello @hsnnalwala !
I am working on a similar project! If you find a way to communicate with the CubeMars through an Arduino, it would be great if you could explain me!

You can refer to the below program which i wrote to control the position of the motor using serial input. `#include <SPI.h>
#include <mcp2515.h>

#define P_MIN -12.5f
#define P_MAX 12.5f
#define V_MIN -50.0f
#define V_MAX 50.0f
#define KP_MIN 0.0f
#define KP_MAX 500.0f
#define KD_MIN 0.0f
#define KD_MAX 5.0f
#define T_MIN -10.0f
#define T_MAX 10.0f

struct can_frame canMsg;

MCP2515 mcp2515(9);

void setup() {

while (!Serial);
Serial.begin(115200);
Serial1.begin(38400);
delay(1000);
while (!Serial);
mcp2515.reset();
mcp2515.setBitrate(CAN_1000KBPS);
mcp2515.setNormalMode();
Serial.println("CAN BUS INIT Succesfully");
Serial1.println("CAN BUS INIT Succesfully");
delay(1000);
//setMotorZero(1);
//Serial.println("Motor set to curr position as zero");
//delay(1000);
enterMotorMode(1);
Serial.println("Motor set to MIT Control Mode");
Serial1.println("Motor set to MIT Control Mode");
delay(1000);
//enterMotorMode(2);

}

void loop()
{

if (Serial1.available() > 0) {
// Default values for vel, kp, kd, torq
float pos, vel = 3, kp = 1, kd = 1, torq = 0;
int mot_id = 1;
String inputString = Serial1.readStringUntil('\n'); // Read the input
Serial.print("Received: "); // Echo received data
Serial.println(inputString);
pos = inputString.toFloat(); // Convert input string to float
sendToMotor(mot_id, pos, vel, kp, kd, torq);
Serial.print("Motor Position sent: ");
Serial.println(pos);
Serial1.print("Motor Position sent: ");
Serial1.println(pos);

}

//sendToMotor(1, 3, 3, 1, 1, 0);
//Serial.println("Motor Position sent 1");
//delay(5000);
//sendToMotor(1, 6, 3, 1, 1, 1);
// delay(5000);
// Serial.println("Motor Position sent 1");
//sendToMotor(1, 0, 3, 1, 1, 1);
// delay(5000);
//Serial.println("Motor Position sent 2");
//sendToMotor(1, 12, 3, 1, 1, 1);
// delay(5000);
//Serial.println("Motor Position sent 3");
//delay(5000);
//sendToMotor(2, 0, 6.28, 0, 5, 0);
//sendToMotor(1, 0, 6.28, 0, 3, 0);
//sendToMotor(2, 0, 6.28, 0, 3, 0);
//delay(1200);

}

void setMotorZero(int mot_id){
struct can_frame cf1;
cf1.can_id = mot_id;
cf1.can_dlc = 8;
cf1.data[0] = 0xFF;
cf1.data[1] = 0xFF;
cf1.data[2] = 0xFF;
cf1.data[3] = 0xFF;
cf1.data[4] = 0xFF;
cf1.data[5] = 0xFF;
cf1.data[6] = 0xFF;
cf1.data[7] = 0xFE;
mcp2515.sendMessage(&cf1);
}

void enterMotorMode(int mot_id){
struct can_frame cf2;
cf2.can_id = mot_id;
cf2.can_dlc = 8;
cf2.data[0] = 0xFF;
cf2.data[1] = 0xFF;
cf2.data[2] = 0xFF;
cf2.data[3] = 0xFF;
cf2.data[4] = 0xFF;
cf2.data[5] = 0xFF;
cf2.data[6] = 0xFF;
cf2.data[7] = 0xFC;
mcp2515.sendMessage(&cf2);
}

void sendToMotor(int mot_id, float pos, float vel, float kp, float kd, float torq){
struct can_frame cf;

unsigned int con_pos = float_to_uint(constrain(pos, P_MIN, P_MAX), P_MIN, P_MAX, 16);
unsigned int con_vel = float_to_uint(constrain(vel, V_MIN, V_MAX), V_MIN, V_MAX, 12);
unsigned int con_kp = float_to_uint(constrain(kp, KP_MIN, KP_MAX), KP_MIN, KP_MAX, 12);
unsigned int con_kd = float_to_uint(constrain(kd, KD_MIN, KD_MAX), KD_MIN, KD_MAX, 12);
unsigned int con_torq = float_to_uint(constrain(torq, T_MIN, T_MAX), T_MIN, T_MAX, 12);
cf.can_id = mot_id;
cf.can_dlc = 8;
cf.data[0] = con_pos>>8;
cf.data[1] = con_pos & 0xFF;
cf.data[2] = con_vel >> 4;
cf.data[3] = ((con_vel&0xF)<<4) | (con_kp>>8);
cf.data[4] = con_kp&0xFF;
cf.data[5] = con_kd>>4;
cf.data[6] = ((con_kd&0xF)<<4) | (con_torq>>8);
cf.data[7] = con_torq&0xFF;
mcp2515.sendMessage(&cf);
}

int float_to_uint(float x, float x_min, float x_max, int bits){
// Converts a float to an unsigned int, given range and number of bits
float span = x_max - x_min;
float offset = x_min;
unsigned int pgg = 0;
if(bits == 12){
pgg = (unsigned int) ((x-offset)*4095.0/span);
}else if(bits == 16){
pgg = (unsigned int) ((x-offset)*65535.0/span);
}
return pgg;
}
`

Hello @hsnnalwala ,

Thanks a lot for the code. Unfortunately, the motor does not moves. You will find a picture of my setup here after. Do you have any idea of what I could have done wrong?

Thanks a lot in advance!

Update: I tried with an Arduino Nano as specified by the arduino-mcp2515 library. However, it still does not work.

Check the CS Pin it might be D9 or D10 depending on the version of your Arduino Board, also check if the CAN communication is successful you can use two sets of Arduinos and can bus shields to test it

Thanks a lot, the issue was that I used the wrong motor ID!

However, I am now trying to get the data from the motor, through interrupts. Did you do this?

Thanks a lot in advance!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.