Reading Servo Motions with a Personal Computer
You need the U2D2, a power supply, and two servos with separate IDs for this tutorial. You do not need the openCM microcontroller. Also, the example code is for Matlab 2021b or later and requires the Communications Toolbox. Python has similar serial communication capabilities.
Why would I want to read information from the Dynamixel smart servos?
Robotics has traditionally focused on calculating and following "trajectories", that is, sequences of robot postures over time. However, an important part of the work we do in this lab is to better understand how animals process sensory feedback as a part of control and how robot performance could be enhanced by such feedback. Therefore, it is important that our robots measure things such as joint angles, angular velocities, joint torques, foot forces, segment bending, and other body states.
How does the servo send information to the main computer?
Reciprocal to the previous tutorial, the servo sends information to the computer, which is temporarily stored in a serial buffer and then read byte-by-byte. The servo sends data in two different contexts:
Dynamixel status packets, as explained previously, and
In response to an instruction packet that contains a "Read" command.
1. Dynamixel status packets
These were explained in the last tutorial, but they are mentioned here briefly to correct a lie by omission. Specifically, every time we called u2d2.write(), the servo sent 6 bytes into the computer's serial port buffer, which we never read. You may want your control program to make use of this information (e.g., if the temperature of a servo becomes too high, set off an alarm or alter the controller to use that servo less), or you may want to clear the buffer so that it does not interfere with later messages you wish to receive (recall that data is read from the buffer first-in-first-out). Here are some options:
If you want to read the packets, use serialport.read(6,"uint8") to take in the message:
comport = "COM3";
baud = double(1000000);
u2d2 = serialport(comport,baud);
%construct a packet to send to the servo
u2d2.write(packet,"uint8");
while u2d2.NumBytesAvailable < 6
%do nothing while we wait for the buffer to fill
end
returnPacket = u2d2.read(u2d2.NumBytesAvailable,"uint8");If you do not wish to read the packets, use serialport.flush() to empty the buffer:
However, this could also delete the info you wanted to read. Thus, the best option may be to read the status return packet every time you send a command, even if you do not use it for anything.
Here's a basic program that does everything:
Here is a function for reading the position, packaged up all together:
Here's a function for setting the position:
Here's a function for calculating the checksum:
Last updated
Was this helpful?