Difference between revisions of "ROBOTIS DYNAMIXEL XL330 Current Based Position Mode (Compliant Mode)"

From Lofaro Lab Wiki
Jump to: navigation, search
(Full Code)
(Code)
Line 112: Line 112:
 
code. To call the header file, we will type in the the
 
code. To call the header file, we will type in the the
 
phrase below:
 
phrase below:
 +
 +
 +
<syntaxhighlight lang="cpp" line='line'>
 +
#include <Dynamixel2Arduino.h>
 +
</syntaxhighlight>
 +
  
  
 
This links the library for the XL330 to our code so that it can operate using the Arduino set up. This also makes it easier to call functions and values as we move forward.
 
This links the library for the XL330 to our code so that it can operate using the Arduino set up. This also makes it easier to call functions and values as we move forward.
 
Now we need to configure the serial ports:
 
Now we need to configure the serial ports:
image
+
 
 +
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
#define DXL_SERIAL Serial1
 +
#define DEBUG_SERIAL Serial
 +
const uint8_t DXL_DIR_PIN = A6;
 +
</syntaxhighlight>
 +
 
 +
 
 
We set the DIR_PIN to A6 so that we change the communication method from full duplex to half duplex.
 
We set the DIR_PIN to A6 so that we change the communication method from full duplex to half duplex.
 
The next step is to set the ID, protocol version and the baud rate, we will assume factory settings as previously stated:
 
The next step is to set the ID, protocol version and the baud rate, we will assume factory settings as previously stated:
  
[[File:code-01.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
const uint8_t DXL_ID = 1;
 +
const float DXL_PROTOCOL_VERSION = 2.0;
 +
const int DXL_BAUD = 57600;
 +
</syntaxhighlight>
 +
 
  
  
 
We now must create the communications object and call the control table as follows:
 
We now must create the communications object and call the control table as follows:
  
[[File:code-02.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);
 +
using namespace ControlTableItem;
 +
</syntaxhighlight>
 +
 
  
 
Configuring the setup function, we must set the baud rate for the debug and then set up the baud rate, protocol version, and ping for the actuator:
 
Configuring the setup function, we must set the baud rate for the debug and then set up the baud rate, protocol version, and ping for the actuator:
  
[[File:code-03.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
void setup() {
 +
  DEBUG_SERIAL.begin(115200);
 +
  dxl.begin(57600);
 +
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
 +
  dxl.ping(DXL_ID);
 +
  dxl.torqueOff(DXL_ID);
 +
  dxl.setOperatingMode(DXL_ID, OP_CURRENT_BASED_POSITION);
 +
  dxl.torqueOn(DXL_ID);
 +
}
 +
</syntaxhighlight>
 +
 
  
 
Note, that we must turn off the torque before we set up the actuator for Current Based Position mode.
 
Note, that we must turn off the torque before we set up the actuator for Current Based Position mode.
Line 136: Line 173:
 
The next task is to set up the loop function. The loop function will consist of setting the goal current and goal position. This is done using the phrases:
 
The next task is to set up the loop function. The loop function will consist of setting the goal current and goal position. This is done using the phrases:
  
[[File:code-04.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
  dxl.setGoalCurrent(DXL_ID, 200);
 +
  dxl.setGoalPosition(DXL_ID, 360.0, UNIT_DEGREE);
 +
</syntaxhighlight>
 +
 
  
 
What these phrases are telling us is that the current will operate at a value of 200 and then we want to set the position to the 360 degree mark on the actuator head. Note that the top notch(single notch) signifies 180 degrees, while the bottom notch(double notches) signifies 360 degrees.
 
What these phrases are telling us is that the current will operate at a value of 200 and then we want to set the position to the 360 degree mark on the actuator head. Note that the top notch(single notch) signifies 180 degrees, while the bottom notch(double notches) signifies 360 degrees.
Line 144: Line 186:
 
If we want to do multiple turns, we must set a delay so that there is prompt time to go from one position to another, or if there is a specific time to go to a position, just like a clock. This is done with:
 
If we want to do multiple turns, we must set a delay so that there is prompt time to go from one position to another, or if there is a specific time to go to a position, just like a clock. This is done with:
  
[[File:code-06.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
delay(1000);
 +
</syntaxhighlight>
 +
 
  
 
This statement delays the system before moving to the next line of code.
 
This statement delays the system before moving to the next line of code.
Line 150: Line 196:
 
The final piece we want to code is the Serial Plotter and Serial Monitor. This is done using:
 
The final piece we want to code is the Serial Plotter and Serial Monitor. This is done using:
  
[[File:code-07.jpg|400px|Because Robots are People Too]]
+
 
 +
<syntaxhighlight lang="cpp" line='line'>
 +
  DEBUG_SERIAL.print("Present Current(raw) : ");
 +
  DEBUG_SERIAL.println(dxl.getPresentCurrent(DXL_ID));
 +
</syntaxhighlight>
 +
 
  
 
This sets up both the plotter and monitor by reading in the raw values that we inputted for current into their respective terminals. You can access these terminals by going to Tools>Serial Monitor or Serial Plotter.
 
This sets up both the plotter and monitor by reading in the raw values that we inputted for current into their respective terminals. You can access these terminals by going to Tools>Serial Monitor or Serial Plotter.

Revision as of 21:43, 16 September 2021

Prerequisites

For this tutorial it is required to have the following items:

  • 1x DYNAMIXEL Shield for Arduino MKR Series
  • 1x Arduino MKR compatible device. Note: This tutorial uses the Arduino MKR Wifi 1010
  • 1x Compatible 1S LiPo battery with a JST2.0 connector (check for proper polarity)
  • Nx DYNAMIXEL XL330-M288-T ROBOTIS actuator(s) where N>=1

Examples

Current Based Position, also known as Torque Based Position, uses the concepts of Position and Current Control modes together to get an actuator to move to a goal position at a certain speed. This mode also helps identify if there is an object in the way of the actuators moving component and can trigger a stop function or a function to add more torque to move the object out of the way. This is a key mode for automated robots that move in a dynamic area where there are obstacles to move around or move entirely.

Video

Overview

This tutorial will also go over how to program the physical XL330 actuator in Current Based Position mode using the DYNAMIXEL Shield with an Arduino MKR. We will begin with how to wire and power the components together to begin programming the actuator. We will then go over the breakdown of the code to have a clear understanding of what each line does and then examine the code as whole. During this tutorial, we will observe how the current and torque are plotted with and without and obstructions to the goal position path. At the end of these tutorials, there will be a link that briefly go over how these concepts are applied physically for a better understanding of what the final outcome should look like.


Tutorials w/Code

Wiring Setup

To review, we must first ping the actuator so that can properly connect to it and continue with the tutorial. First we must properly wire and connect all components for this to happen. The following steps provide how to properly connect all components together:

MKR Hookup Part 1

Connect the DYNAMIXEL Shield on top or below the Arduino MKR of your choosing. The header pins will show slightly. DO NOT TRY TO FORCE THE PINS ALL THE WAY DOWN OR YOU WILL DAMAGE YOUR COMPONENTS.

Because Robots are People Too


MKR Hookup Part 2

Attach the female to female end wire to the shield in any of the 3 ports. Notice that the wire is keyed so that is inserted in a certain way.

MKR Hookup Part 3

Attach the other female end of that same wire to one of the actuators.

Because Robots are People Too

MKR Hookup Part 4

Attach your battery to the JST2.0 battery port on the Shield so that the actuator can be powered. Do not connect the battery to the MKR or the actuator will not power

Because Robots are People Too

NOTE: If the actuator is running in factory settings, it will blink once when it is powered and will have the following attributes:

Because Robots are People Too


MKR Hookup Part 5

The final step is to take the USB device that came with the Arduino MKR and connect it to your computer and Arduino MKR series device. The final setup is shown as: Because Robots are People Too


Code

To continue on, make sure you have downloaded the DYNAMIXEL Protocol Headers for Arduino. You can find a tutorial here at this link.[1]

Now that the header files are downloaded, I recommend look over the examples to familiarize yourself with the other modes. For this tutorial, I will be referencing the Dynamixel2Arduino current_based_position example provided.

We will begin by setting up the header files and teh global variables that we will be using throughout the code. To call the header file, we will type in the the phrase below:


  1. #include <Dynamixel2Arduino.h>


This links the library for the XL330 to our code so that it can operate using the Arduino set up. This also makes it easier to call functions and values as we move forward. Now we need to configure the serial ports:


  1. #define DXL_SERIAL Serial1
  2. #define DEBUG_SERIAL Serial
  3. const uint8_t DXL_DIR_PIN = A6;


We set the DIR_PIN to A6 so that we change the communication method from full duplex to half duplex. The next step is to set the ID, protocol version and the baud rate, we will assume factory settings as previously stated:


  1. const uint8_t DXL_ID = 1;
  2. const float DXL_PROTOCOL_VERSION = 2.0;
  3. const int DXL_BAUD = 57600;


We now must create the communications object and call the control table as follows:


  1. Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);
  2. using namespace ControlTableItem;


Configuring the setup function, we must set the baud rate for the debug and then set up the baud rate, protocol version, and ping for the actuator:


  1. void setup() {
  2.   DEBUG_SERIAL.begin(115200);
  3.   dxl.begin(57600);
  4.   dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  5.   dxl.ping(DXL_ID);
  6.   dxl.torqueOff(DXL_ID);
  7.   dxl.setOperatingMode(DXL_ID, OP_CURRENT_BASED_POSITION);
  8.   dxl.torqueOn(DXL_ID);
  9. }


Note, that we must turn off the torque before we set up the actuator for Current Based Position mode. This is key since we can’t change modes without performing this task.

The next task is to set up the loop function. The loop function will consist of setting the goal current and goal position. This is done using the phrases:


  1.   dxl.setGoalCurrent(DXL_ID, 200);
  2.   dxl.setGoalPosition(DXL_ID, 360.0, UNIT_DEGREE);


What these phrases are telling us is that the current will operate at a value of 200 and then we want to set the position to the 360 degree mark on the actuator head. Note that the top notch(single notch) signifies 180 degrees, while the bottom notch(double notches) signifies 360 degrees.

Because Robots are People Too

If we want to do multiple turns, we must set a delay so that there is prompt time to go from one position to another, or if there is a specific time to go to a position, just like a clock. This is done with:


  1. delay(1000);


This statement delays the system before moving to the next line of code.

The final piece we want to code is the Serial Plotter and Serial Monitor. This is done using:


  1.   DEBUG_SERIAL.print("Present Current(raw) : ");
  2.   DEBUG_SERIAL.println(dxl.getPresentCurrent(DXL_ID));


This sets up both the plotter and monitor by reading in the raw values that we inputted for current into their respective terminals. You can access these terminals by going to Tools>Serial Monitor or Serial Plotter.

Once this is all done, we must now verify and compile the code. We verify by clicking the check mark at the top right of the IDE and then compile and upload the code using the right facing arrow right next to it.

Because Robots are People Too

Once we have done both of those things, we can watch the actuator move as we instruct it.

We also want to note how the plotter and monitor read when we provide a counter torque to the device. If we apply a torque in the opposite direction, the current will increase to try and get the actuator to move. If the counter torque is higher than the max amount of current the actuator can provide, then it will not move and the current will spike up and stay at or near max. If we add a torque to the torque, then the actuator will send in a negative current to try and stay at that speed. When there is not added torque, we will see a constant waveform that corresponds with the input current. An example of a graph with a counter torque is shown as:

Because Robots are People Too

Full Code

Below is the full code assembled. Note that some variables are changed to show that you can edit the position and current goal values to fit your desired needs. This code is referenced off of the setup from the examples provided by DYNMIXEL’s library. To find these examples you will go to File>Examples. From here you need to scroll down the menu to where it says Dynamixel2Arduino then go from there to “basic” and then select the mode you would like to review.

Because Robots are People Too

  1. #include <Dynamixel2Arduino.h>
  2. #define DXL_SERIAL Serial1
  3. #define DEBUG_SERIAL Serial
  4. const uint8_t DXL_DIR_PIN = A6;
  5. const uint8_t DXL_ID = 1;
  6. const float DXL_PROTOCOL_VERSION = 2.0;
  7. const int DXL_BAUD = 57600;
  8. Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);
  9. using namespace ControlTableItem;
  10. void setup() {
  11.   DEBUG_SERIAL.begin(115200);
  12.   dxl.begin(57600);
  13.   dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  14.   dxl.ping(DXL_ID);
  15.   dxl.torqueOff(DXL_ID);
  16.   dxl.setOperatingMode(DXL_ID, OP_CURRENT_BASED_POSITION);
  17.   dxl.torqueOn(DXL_ID);
  18. }
  19. void loop() {
  20.  
  21.   dxl.setGoalCurrent(DXL_ID, 200);
  22.   dxl.setGoalPosition(DXL_ID, 360.0, UNIT_DEGREE);
  23.   delay(50);
  24.   DEBUG_SERIAL.print("Present Current(raw) : ");
  25.   DEBUG_SERIAL.println(dxl.getPresentCurrent(DXL_ID));
  26.   delay(1000);
  27.   dxl.setGoalCurrent(DXL_ID, 300);
  28.   dxl.setGoalPosition(DXL_ID, 0.0, UNIT_DEGREE);
  29.   delay(5000);
  30. }