MJ-VESCuino
MJ-VESC stackable on Arduino
If you have any question on MJ-VESC, please leave a topic on 'Board' or send a email to [email protected]

MJ-VESC ver0.1

Stacked three MJ-VESCs with 3D printed Case.

Stacked four MJ-VESCs on Arduino Due with 3D printed Case.
- 1.In FOC control, we provide high torque control even at low speed.
- 2.Position control is possible at Hall sensor commutation with AB encoder (without index).
- 3.Hall & Encoder Hybrid Commutation for more precise position control.
- 4.More accurate current control by changing shunt resistor from 0.5mohm to 2mohm.
- 5.Improved CAN Communication Noise Filter using split terminal resistor and EMI filter.
- 1.High accuracy position control using "DPS speed control" (Degree Per Second).
- 2.VESC - Arduino high speed communication using SPI communication.
- 3.Debugging terminal using extra serial communication.
The MJ-VESC Firmware version is based on vesc bldc firmware 3.40 and compatible VESC-TOOL version is 0.95 at this moment.
In this page, I will explain how to setup MJ-VESC when the high-level controller is based on ROS and communication method is USB.
1. First, run VESC-TOOL (I assume that the motor setup of all the MJ-VESC is already finished)
./vesc_tool_0.95
Connect MJ-VESC ID=0.
Go to App Settings -> General -> APP to USE : Custom User App
Go to App Settings -> General -> Send CAN Status : False.
2. Connect MJ-VESC ID=1~ using CAN-FORWARD (Setup all the other MJ-VESCs as below in case of ID>=1)
Go to App Settings -> General -> APP to USE : UART
Go to App Settings -> General -> Send CAN Status : True
The VESC-TOOL setup is finished.
3. Download attached source code named 'vesc_control_ex1.zip'. You also need vesc library for ROS. Download 'vesc.zip' which is ros driver for MJ-VESC.
4. Unzip and put those folders at your catkin workspace and then build. When you build, you may need dependencies as follows:
serial
ackermann-msgs
You can install above packages like this (when you use 'ros-melodic' then replace 'kinetic' to 'melodic').
sudo apt-get install ros-kinetic-ackermann-msgs ros-kinetic-serial
5. Run the ROS example using launch file below. Change argument 'port' depend on your condition.
roslaunch vesc_control_ex1 vesc_control_ex1_teleop.launch port:=/dev/ttyACM1
The main function of 'vesc_control_ex1_node.cpp' is as below.
/*
* Main Function
*
*/
int main(int argc, char **argv)
{
ros::init(argc, argv, "vesc_control_node");
// loop freq
int rate_hz = 50; //hz
// TeleopVesc Class
const int num_of_vesc = VESC_ID_END+1;//4;
TeleopVesc *teleop_vesc = new TeleopVesc(num_of_vesc);
teleop_vesc->enable.data = false;
// ROS Loop
int cnt_lp = 0;
ros::Rate loop_rate(rate_hz); //Hz
ROS_INFO("Start Tele-operation");
while (ros::ok())
{
teleop_vesc->enable.data = true;
// read encoder data.
//teleop_vesc->requestCustoms();
//ROS_INFO("rps_0:%.2f(dps_0:%.2f), rad_0:%.2f", teleop_vesc->rps[0], teleop_vesc->rps[0]*RPS2DPS, teleop_vesc->rad[0]);
//ROS_INFO("rps_1:%.2f(dps_1:%.2f), rad_1:%.2f", teleop_vesc->rps[1], teleop_vesc->rps[1]*RPS2DPS, teleop_vesc->rad[1]);
//ROS_INFO("rps_2:%.2f(dps_2:%.2f), rad_2:%.2f", teleop_vesc->rps[2], teleop_vesc->rps[2]*RPS2DPS, teleop_vesc->rad[2]);
//ROS_INFO("rps_3:%.2f(dps_3:%.2f), rad_3:%.2f", teleop_vesc->rps[3], teleop_vesc->rps[3]*RPS2DPS, teleop_vesc->rad[3]);
// // current example (A)
//teleop_vesc->current[0] = 4.0;
//teleop_vesc->current[1] = 4.0;
//teleop_vesc->current[2] = -1.0;
//teleop_vesc->current[3] = 1.0;
//teleop_vesc->setCurrentOut();
// // brake example (A)
//teleop_vesc->brake[0] = 10.0;
//teleop_vesc->brake[1] = 10.0;
//teleop_vesc->brake[2] = 5.0;
//teleop_vesc->brake[3] = 8.0;
//teleop_vesc->setBrakeOut();
// // speed example (erpm = rev/min*polepair, polepair=Encoder [email protected]_tool)
//teleop_vesc->speed[0] = 0.//-(15000.0 - 5000.0);
//teleop_vesc->speed[1] = 1000.//(15000.0 + 5000.0);
//teleop_vesc->speed[2] = -1000.0;
//teleop_vesc->speed[3] = 5000.0;
//teleop_vesc->setSpeedOut();
// // duty example (0.005~0.95)
//teleop_vesc->duty[0] = 0.1;
//teleop_vesc->duty[1] = 0.1;
//teleop_vesc->duty[2] = 0.1;
//teleop_vesc->duty[3] = 0.5;
//teleop_vesc->setDutyCycleOut();
// // position example (0~360 deg)
//teleop_vesc->position[0] = 0.;
//teleop_vesc->position[1] = 15.;
//teleop_vesc->position[2] = 270.;
//teleop_vesc->position[3] = -45.;
//teleop_vesc->setPositionOut();
// Custom example
teleop_vesc->custom_cmd_type[0] = COMM_SET_DUTY;
teleop_vesc->custom_cmd_value[0] = 0.6;
teleop_vesc->custom_cmd_type[1] = COMM_SET_DPS;
teleop_vesc->custom_cmd_value[1] = 1000.;
//teleop_vesc->custom_cmd_type[2] = COMM_SET_DPS;
//teleop_vesc->custom_cmd_value[2] = -1000.;
//teleop_vesc->custom_cmd_type[3] = COMM_SET_DPS;
//teleop_vesc->custom_cmd_value[3] = 1000.;
//teleop_vesc->custom_cmd_type[1] = COMM_SET_DPS;
//teleop_vesc->custom_cmd_value[1] = 0.;
teleop_vesc->setCustomOut();
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
You can test 'SetCurrent', 'SetDutyCycle', 'SetSpeed', 'SetPosition', 'SetBrake', 'SetDPS' by un-commenting each functions. "COMM_SET_DPS" is only valid when you use 'teleop_vesc->custom_cmd_type'.
All the encoder data are stored at 'teleop_vesc->rps[id]' and 'teleop_vesc->rad[id]'. The 'rps' is rad/sec' and The 'rad' is Radian. You can easily use these variables at main function.
vesc.zip
49KB
Binary
VESC ROS Driver
vesc_control_ex1.zip
6KB
Binary
Last modified 2yr ago