brbrain
Class BRBrain

java.lang.Object
  extended by brbrain.BRBrain

public class BRBrain
extends java.lang.Object

Bioloid Remote Brain library.

This is a Java host library, which, combined with custom C firmware, implements remote brain functionality for the Robotis Bioloid.

High level documentation and instructions for installing the custom CM-5 firmware are available from the BRBrain homepage.

Java Code Runs Off-Board

This system allows you to write Java code to control Bioloid constructions. The Java code always runs on a host PC and communicates with the CM-5 on your Bioloid hardware via a serial link. Sensor and actuator data is exchanged in near real time between the CM-5 and a host workstation, allowing high-level control code to run (and be debugged) directly on the workstation.

Again, BRBrain does not allow you to run Java code directly on the CM-5. You run Java code on a host PC that communicates with the CM-5 over either the standard RS232 serial cable or an optional non-standard bluetooth link that you can add to your CM-5 as described here.

Establishing Communications

Several constructors are provided to allow the actual communication link between the host PC and the CM-5 to be implemented in different ways:

The RXTX codepath has the advantage of internally setting the communications parameters (115.2kbps, 8N1, no flow control). The regular file codepath will require the serial port to be externally configured (e.g. using stty on Linux). The serial port must be 8-bit clean. This is automatically guaranteed when using RXTX. For the regular file codepath it is part of the external port configuration. For example, on Linux the terminal driver associated with the port device needs to be taken out of "cooked" mode (the default) and placed in "raw" mode (again using stty).

listPorts(java.io.PrintStream) may be invoked to get a list of the port names that the RXTX library believes to be available.

Talking to the Bioloid

The CM-5 running the custom firmware acts as a relay between the register banks of the connected network of Dynamixel AX modules and the host PC. The AX12Register and AXS1Register classes enumerate the Dynamixel registers that you can access. Refer to the respective manuals for Dynamixel register descriptions.

For performance, you first inform BRBrain of the set of particular registers on particular Dynamixels in which you are interested. Such a specificiation is called a format; you specify separate formats for data that you are writing from the host PC to the Dynamixels and data that you are reading from the Dynamixels to the host PC with the setWriteFormat(int[], brbrain.AXRegister[], int[]) and setReadFormat(int[], brbrain.AXRegister[], int[]) APIs, respectively.

Once you have specified your read and write formats, you read and write blocks of data from and to the Dynamixels by calling the read(int[]), read(float[]), and write(int[]) and write(float[]) APIs. The integer versions of these APIs read and write raw integer values from/to the Dynamixels; the float versions automatically convert natural units for the register from/to the raw register values. For example, the natural units for the AX12Register.AX12_PRESENT_POSITION register are degrees.

To keep format specification simple, you can only specify one contiguous block of registers to read and a separate contiguous block of registers to write per Dynamixel. The blocks can be different on different Dynamixels, and you can specify an arbitrary set of Dynamixel IDs to which you will be communicating; this set need not include all of the Dynamixels that are actually connected to your CM-5. On a write, all registers are written in synchrony with the REG_WRITE/ACTION instructions supported by the Dynamixels.

A cache of most-recently read data is maintained and may be queried with getCachedValue(int, brbrain.AXRegister).

Every method which involves actual communication with the CM-5 is synchronized. Synchronize on the BRBrain object to perform multiple communications in a single uninterrupted transaction.

Usage Example

First, get a list of the available serial ports:

 BRBrain.listPorts();
 
The output will depend on your operating system and the serial port hardware actually available on your computer. You'll need to interpret it and figure out the port to which your CM-5 is actually connected. For example, on Linux this might be /dev/ttyS0 or /dev/ttyUSB0 if the CM-5 is connected to the first built-in serial port or to the first USB-to-serial adapter, respectively. On windows it may be something like COM1.

Next, create a BRBrain object. This establishes communications:

 BRBrain b = new BRBrain("/dev/ttyS0"); //or whatever port you selected
 

Now set read and write formats. Let's say you want to read the five AX-12 registers starting at AX12Register.AX12_PRESENT_POSITION (these also include AX12Register.AX12_PRESENT_SPEED, AX12Register.AX12_PRESENT_LOAD, AX12Register.AX12_PRESENT_VOLTAGE, and AX12Register.AX12_PRESENT_TEMPERATURE), write only the AX12Register.AX12_GOAL_POSITION, and that you want to do this on two AX-12s with IDs 3 and 7:

 int status =
   b.setReadFormat(new int[] {3, 7}, //id
                   new AXRegister{AX12Register.AX12_PRESENT_POSITION, //start
                                  AX12Register.AX12_PRESENT_POSITION},
                   new int{5, 5}); //num
 b.verifyStatus(status, "set read format");

 status = 
   b.setWriteFormat(new int[] {3, 7}, //id
                   new AXRegister{AX12Register.AX12_GOAL_POSITION,  //start
                                  AX12Register.AX12_GOAL_POSITION},
                   new int{1, 1}); //num
 b.verifyStatus(status, "set write format");
 

Finally, you can set some goal positions and then monitor the state of your two servos:

 //sets servo 3 to goal position 100 degrees, servo 7 to 200 degrees
 status = b.write(new float[] {100.0f, 200.0f});
 b.verifyStatus(status, "set goal positions");

 float[] state = new float[2*5];
 status = b.read(state);
 b.verifyStatus(status, "read state");
 

Extra Utilities

You can use the BRBrain class alone (well, AXRegister and its subclasses are also required) in your programs. Some additional utilities are also included in this package which can help you implement recording and playing back motion sequences, or just displaying a GUI with little read/write boxes for all the Dynamixel register values:

Under the Hood

This section documents the variable-length packet communication protocol that BRBrain uses to communicate with the custom firmware. If you are just using BRBrain to write Java control programs for your Bioloid, and you are not intending to modify the firmware, you can skip this section.

All packets sent in either direction follow the basic format


 instruction
 [data...]
 checksum
 
 
where "instruction" is one byte long, data is zero or more bytes, and checksum is computed as the bitwise inverse of the unsigned byte sum of the data and the instruction.

The following instructions are used for packets from the host to the CM-5:

The following instructions are used for packets from the CM-5 to the host:

Copyright (C) 2008 Marsette A. Vona, III

Author:
Marsette (Marty) A. Vona, III

Nested Class Summary
 class BRBrain.CachedValue
          a cached register value
static class BRBrain.Instruction
          BRBrain protocol packet instructions, see BRBrain class header doc for details.
 
Field Summary
protected  int[] adcValue
          most recently read raw 8-bit ADC values
protected  int[][] axID
          dynamixel ids in current F_READ and F_WRITE
protected  java.util.Map<AXRegister,java.util.Map<java.lang.Integer,BRBrain.CachedValue>> cache
          cache of most recently read data
static int CHANNEL_NEG
          ADC channel connected to the negative battery terminal
static int CHANNEL_POS
          ADC channel connected to the positive battery terminal
static int CHANNEL_THERM
          ADC channel connected to the thermistor
protected  int checksum
          checksum in progress
static int CM5_BOOTLOADER_BAUDRATE
          baudrate at which the CM-5 bootloader likes to talk
static java.lang.String CM5_BOOTLOADER_MSG
          CM-5 bootloader welcome message
 boolean debug
          whether to show protocol debug messages
static int DEF_TIMEOUT_MS
          default receive timout in ms
 boolean enableRecvPacketDebug
          whether to enable debug log of failed recv packets
protected static int F_READ
          read format
protected static int F_WRITE
          write format
static int FLASH_DELAY_MS
          delay between stages of the flashCM5(java.io.InputStream, java.io.PrintStream) procedure
static double FLASH_TIMEOUT_MS
          timeout for response from the CM-5 during flashCM5(java.io.InputStream, java.io.PrintStream)
protected static BRBrain.Instruction[] FMT_INSTRUCTION
          set format instructions
protected  java.io.InputStream fromCM5
          input stream from CM-5
static int MAX_DYNAMIXELS
          maximum number of dynamixels in a format
protected  int[] numDynamixels
          num dynamixels in current F_READ and F_WRITE
protected  int[][] numReg
          num regs in current F_READ and F_WRITE
static int RECOVER_MS
          ms to wait before draining recv buffer in recover()
static int RECV_POLL_MS
          receive poll time in ms
protected  boolean recvPacketDebug
          whether to log to recvPacketDebugBuffer
protected  java.util.List<java.lang.Byte> recvPacketDebugBuffer
          debug log for recv packets
static int RXTX_DEF_BAUD_RATE
          default baudrate for RXTX
static int RXTX_OPEN_TIMEOUT_MS
          timeout in ms to wait to open a port with RXTX
static java.lang.String RXTX_PORT_OWNER_NAME
          RXTX port owner name
static int S_DYNAMIXEL_CHECKSUM_ERROR
          CM-5 status bit
static int S_DYNAMIXEL_RX_OVERFLOW
          CM-5 status bit
static int S_DYNAMIXEL_TIMEOUT
          CM-5 status bit
static int S_INVALID_DYNAMIXEL_RESPONSE
          CM-5 status bit
static int S_INVALID_PC_COMMAND
          CM-5 status bit
static int S_PC_CHECKSUM_ERROR
          CM-5 status bit
static int S_PC_RX_OVERFLOW
          CM-5 status bit
static int S_PC_TIMEOUT
          CM-5 status bit
protected  gnu.io.SerialPort serialPort
          serial port talking to the CM-5
protected  AXRegister[][] startReg
          start regs in current F_READ and F_WRITE
private static java.lang.String svnid
           
protected  double timeoutMS
          timout in ms to wait for a response byte from the CM-5
protected  java.io.OutputStream toCM5
          output stream to CM-5
protected  int[] totalNumRegs
          total num regs in current F_READ and F_WRITE
 
Constructor Summary
BRBrain(java.io.File port)
          Same as BRBrain(String) but connect to CM-5 via a file instead of with RXTX.
BRBrain(java.lang.String portName)
          covers BRBrain(String, int) uses RXTX_DEF_BAUD_RATE
BRBrain(java.lang.String portName, int baudRate)
          Setup an BRBrain talking to a CM-5 on the specified serial port at the specified baud rate.
 
Method Summary
static float adcToVolts(int value)
          convert a raw ADC reading to V at the input of the 3.3k/10k divider
static void checkAXIDs(int[] id)
          covers checkAXIDs(int[], int), checks all
static void checkAXIDs(int[] id, int n)
          verify the first n dynamixel ids in the given array are unique
protected  void checkFmtSame(AXRegister[] start, int n)
          ensure that all initial n elements of start are equal
protected  void checkFmtSame(int[] num, int n)
          ensure that all initial n elements of num are equal
 void close()
          close the serial port, no further comms possible
protected  void dbg(java.lang.String msg, int b)
          print a debug message for a byte
protected  void drainFromCM5()
          drain fromCM5
static boolean[] dup(boolean[] from, boolean[] to)
          covers dup(boolean[], boolean[], int), copies all
static boolean[] dup(boolean[] from, boolean[] to, int n)
          duplicate first n element of from into to, reallocating as necessary
static int[] dup(int[] from, int[] to)
          covers dup(int[], int[], int), copies all
static int[] dup(int[] from, int[] to, int n)
          duplicate first n element of from into to, reallocating as necessary
static java.lang.String[] dup(java.lang.String[] from, java.lang.String[] to)
          covers dup(String[], String[], int), copies all
static java.lang.String[] dup(java.lang.String[] from, java.lang.String[] to, int n)
          duplicate first n element of from into to, reallocating as necessary
protected  void endRecvPacket()
          end an incoming packet, validating checksum
protected  void endSendPacket()
          end an outgoing packet, sending checksum
static boolean[] ensureCapacity(boolean[] a, int n)
          make sure a is at least length n
static int[] ensureCapacity(int[] a, int n)
          make sure a is at least length n
static java.lang.String[] ensureCapacity(java.lang.String[] a, int n)
          make sure a is at least length n
protected  void finalize()
          close()s
 int flashCM5(java.io.File binary, java.io.PrintStream log)
          covers flashCM5(InputStream, PrintStream)
 int flashCM5(java.io.InputStream binary, java.io.PrintStream log)
          Interact with the user and the CM-5 bootloader to flash new firmware to the CM-5.
 int flashCM5(java.lang.String binary)
          covers flashCM5(String, PrintStream), uses System.out
 int flashCM5(java.lang.String binary, java.io.PrintStream log)
          covers flashCM5(File, PrintStream)
 int getADC(int channel)
          get the most recent ADC reading for the given channel
 BRBrain.CachedValue getCachedValue(int axID, AXRegister register)
          Look up the most recent BRBrain.CachedValue of of the specified reg, null if none.
protected  int getFormat(int f, int[] id, AXRegister[] start, int[] num)
          Common impl of getReadFormat(int[], brbrain.AXRegister[], int[]) and getWriteFormat(int[], brbrain.AXRegister[], int[]).
 int getNumReadDynamixels()
          get the number of dynamixels in the current read format
 int getNumWriteDynamixels()
          get the number of dynamixels in the current write format
 java.lang.Object[] getReadFormat()
          Covers getReadFormat(int[], brbrain.AXRegister[], int[]), uses packFormat(int, int[], brbrain.AXRegister[], int[]), for jscheme API convenience.
 int getReadFormat(int[] id, AXRegister[] start, int[] num)
          Get a copy of the most recently setReadFormat(int[], brbrain.AXRegister[], int[]), see which.
 double getTimeoutMS()
          get the current timeout for a response from the CM-5 in ms
 int getTotalNumReadRegs()
          get the total number of registers in the current read format
 int getTotalNumWriteRegs()
          get the total number of registers in the current write format
 java.lang.Object[] getWriteFormat()
          Covers getWriteFormat(int[], brbrain.AXRegister[], int[]), uses packFormat(int, int[], brbrain.AXRegister[], int[]), for jscheme API convenience.
 int getWriteFormat(int[] id, AXRegister[] start, int[] num)
          Get a copy of the most recently setWriteFormat(int[], brbrain.AXRegister[], int[]), see which.
static java.io.PrintStream listPorts()
          covers listPorts(PrintStream), uses System.out
static java.io.PrintStream listPorts(java.io.PrintStream printStream)
          Convenience method to query the list of available ports according to RXTX.
protected  java.lang.Object[] packFormat(int n, int[] id, AXRegister[] start, int[] num)
          Pack read or write format from a contiguous array, for convienience of the scheme API.
protected  java.lang.Object[] parseFormatArgs(java.lang.Object[] args)
          Parse read or write format from a contiguous array, for jscheme API convienience.
 int pingCM5()
          covers pingDynamixel(int), uses id 255 to ping the CM-5 itself
 int pingDynamixel(int id)
          Issue BRBrain.Instruction.I_PING packet requesting ping of the indicated dynamixel.
 int[] read()
          Read int register values and CM-5 status into an array, for jscheme API convenience.
 int read(float[] data)
          Read data from dynamixels in natural units according to the current read format.
 int read(int[] data)
          same as read(float[]) but reads register ints directly
protected  int read(java.lang.Object data)
          common impl of read(float[]) and read(int[])
 float[] readNatural()
          Read natural register values and CM-5 status into an array, for jscheme API convenience.
 void recover()
          waits RECOVER_MS and then drains recv buf
protected  void recvADCs()
          receive and store the ADC channel readings in adcValue
protected  int recvByte()
          covers recvByte(boolean), always adds to checksum
protected  int recvByte(boolean addToChecksum)
          Receive a byte from the CM-5.
protected  int recvStatus()
          receive a BRBrain.Instruction.I_STATUS packet, return payload
 boolean[] scan(boolean[] dynamixels, int maxID)
          Scan for presence of dynamixels with IDs in the closed interval [0, maxID].
 boolean[] scan(int maxID)
          covers scan(boolean[], int), always conses
protected  void sendByte(int b)
          covers sendByte(int, boolean), always adds to checksum
protected  void sendByte(int b, boolean addToChecksum)
          Send a byte to the CM-5.
protected  void setBaudRate(int baudRate)
          attempt to set the baud rate, works only if using RXTX
protected  int setFormat(int f, int[] id, AXRegister[] start, int[] num)
          Common impl of setReadFormat(int[], brbrain.AXRegister[], int[]) and setWriteFormat(int[], brbrain.AXRegister[], int[]).
 int setReadFormat(int[] id, AXRegister[] start, int[] num)
          Set the read format as described in the class header doc.
 int setReadFormat(java.lang.Object[] args)
          Covers setReadFormat(int[], brbrain.AXRegister[], int[]), uses parseFormatArgs(java.lang.Object[]), for jscheme API convenience.
 double setTimeoutMS(double timeoutMS)
          set the timeout for a response from the CM-5 in ms, returns old value
 int setWriteFormat(int[] id, AXRegister[] start, int[] num)
          Similar to setReadFormat(int[], brbrain.AXRegister[], int[]).
 int setWriteFormat(java.lang.Object[] args)
          Covers setWriteFormat(int[], brbrain.AXRegister[], int[]), uses parseFormatArgs(java.lang.Object[]), for jscheme API convenience.
protected  void startRecvPacket(BRBrain.Instruction instruction)
          start an incoming packet expecting the given instruction
protected  void startSendPacket(BRBrain.Instruction instruction)
          start an outgoing packet with the given instruction
static java.lang.String statusToString(int status)
          Covers statusToString(int, StringBuffer)
static java.lang.StringBuffer statusToString(int status, java.lang.StringBuffer buf)
          Compose a human-readable string of CM-5 status from a CM-5 status byte.
protected  void updateCachedValue(int axID, AXRegister register, int value)
          update cache
static void verifyStatus(int status, java.lang.String operation)
          covers verifyStatus(int, String, boolean), not warn
static boolean verifyStatus(int status, java.lang.String operation, boolean warnOnly)
          Verify a CM-5 return status code/retry count.
 int write(float[] data)
          Write data to dynamixels in natural units according to the current write format.
 int write(int[] data)
          same as write(float[]) but writes register ints directly
 int write(java.lang.Object data)
          common impl of write(float[]) and write(int[])
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

svnid

private static final java.lang.String svnid
See Also:
Constant Field Values

debug

public boolean debug
whether to show protocol debug messages


enableRecvPacketDebug

public boolean enableRecvPacketDebug
whether to enable debug log of failed recv packets


recvPacketDebug

protected boolean recvPacketDebug
whether to log to recvPacketDebugBuffer


recvPacketDebugBuffer

protected java.util.List<java.lang.Byte> recvPacketDebugBuffer
debug log for recv packets


cache

protected java.util.Map<AXRegister,java.util.Map<java.lang.Integer,BRBrain.CachedValue>> cache
cache of most recently read data


RXTX_PORT_OWNER_NAME

public static final java.lang.String RXTX_PORT_OWNER_NAME
RXTX port owner name

See Also:
Constant Field Values

RXTX_OPEN_TIMEOUT_MS

public static final int RXTX_OPEN_TIMEOUT_MS
timeout in ms to wait to open a port with RXTX

See Also:
Constant Field Values

DEF_TIMEOUT_MS

public static final int DEF_TIMEOUT_MS
default receive timout in ms

See Also:
Constant Field Values

RECV_POLL_MS

public static final int RECV_POLL_MS
receive poll time in ms

See Also:
Constant Field Values

RECOVER_MS

public static final int RECOVER_MS
ms to wait before draining recv buffer in recover()

See Also:
Constant Field Values

RXTX_DEF_BAUD_RATE

public static final int RXTX_DEF_BAUD_RATE
default baudrate for RXTX

See Also:
Constant Field Values

S_PC_TIMEOUT

public static final int S_PC_TIMEOUT
CM-5 status bit

See Also:
Constant Field Values

S_DYNAMIXEL_TIMEOUT

public static final int S_DYNAMIXEL_TIMEOUT
CM-5 status bit

See Also:
Constant Field Values

S_INVALID_PC_COMMAND

public static final int S_INVALID_PC_COMMAND
CM-5 status bit

See Also:
Constant Field Values

S_INVALID_DYNAMIXEL_RESPONSE

public static final int S_INVALID_DYNAMIXEL_RESPONSE
CM-5 status bit

See Also:
Constant Field Values

S_PC_RX_OVERFLOW

public static final int S_PC_RX_OVERFLOW
CM-5 status bit

See Also:
Constant Field Values

S_DYNAMIXEL_RX_OVERFLOW

public static final int S_DYNAMIXEL_RX_OVERFLOW
CM-5 status bit

See Also:
Constant Field Values

S_PC_CHECKSUM_ERROR

public static final int S_PC_CHECKSUM_ERROR
CM-5 status bit

See Also:
Constant Field Values

S_DYNAMIXEL_CHECKSUM_ERROR

public static final int S_DYNAMIXEL_CHECKSUM_ERROR
CM-5 status bit

See Also:
Constant Field Values

MAX_DYNAMIXELS

public static final int MAX_DYNAMIXELS
maximum number of dynamixels in a format

See Also:
Constant Field Values

F_READ

protected static final int F_READ
read format

See Also:
Constant Field Values

F_WRITE

protected static final int F_WRITE
write format

See Also:
Constant Field Values

FMT_INSTRUCTION

protected static final BRBrain.Instruction[] FMT_INSTRUCTION
set format instructions


CM5_BOOTLOADER_BAUDRATE

public static final int CM5_BOOTLOADER_BAUDRATE
baudrate at which the CM-5 bootloader likes to talk

See Also:
Constant Field Values

FLASH_TIMEOUT_MS

public static final double FLASH_TIMEOUT_MS
timeout for response from the CM-5 during flashCM5(java.io.InputStream, java.io.PrintStream)

See Also:
Constant Field Values

FLASH_DELAY_MS

public static final int FLASH_DELAY_MS
delay between stages of the flashCM5(java.io.InputStream, java.io.PrintStream) procedure

See Also:
Constant Field Values

CM5_BOOTLOADER_MSG

public static final java.lang.String CM5_BOOTLOADER_MSG
CM-5 bootloader welcome message

See Also:
Constant Field Values

CHANNEL_POS

public static final int CHANNEL_POS
ADC channel connected to the positive battery terminal

See Also:
Constant Field Values

CHANNEL_NEG

public static final int CHANNEL_NEG
ADC channel connected to the negative battery terminal

See Also:
Constant Field Values

CHANNEL_THERM

public static final int CHANNEL_THERM
ADC channel connected to the thermistor

See Also:
Constant Field Values

adcValue

protected int[] adcValue
most recently read raw 8-bit ADC values


serialPort

protected gnu.io.SerialPort serialPort
serial port talking to the CM-5


toCM5

protected java.io.OutputStream toCM5
output stream to CM-5


fromCM5

protected java.io.InputStream fromCM5
input stream from CM-5


timeoutMS

protected double timeoutMS
timout in ms to wait for a response byte from the CM-5


checksum

protected int checksum
checksum in progress


numDynamixels

protected int[] numDynamixels
num dynamixels in current F_READ and F_WRITE


totalNumRegs

protected int[] totalNumRegs
total num regs in current F_READ and F_WRITE


axID

protected int[][] axID
dynamixel ids in current F_READ and F_WRITE


startReg

protected AXRegister[][] startReg
start regs in current F_READ and F_WRITE


numReg

protected int[][] numReg
num regs in current F_READ and F_WRITE

Constructor Detail

BRBrain

public BRBrain(java.lang.String portName,
               int baudRate)
        throws java.io.IOException,
               java.lang.InterruptedException

Setup an BRBrain talking to a CM-5 on the specified serial port at the specified baud rate.

Note that this method does no transmission on the port, and does not verify the presence of a CM-5 running the correct firmware.

A recover() is performed.

Parameters:
portName - an RXTX serial port name, see listPorts(java.io.PrintStream)
baudRate - the baud rate in bits per second
Throws:
java.io.IOException - if there was a problem opening the port
java.lang.InterruptedException - if interrupted during recover()
java.lang.IllegalStateException - if the specified port is not recognized by RXTX as a serial port, or if RXTX silently failed to open the port

BRBrain

public BRBrain(java.lang.String portName)
        throws java.io.IOException,
               java.lang.InterruptedException
covers BRBrain(String, int) uses RXTX_DEF_BAUD_RATE

Throws:
java.io.IOException
java.lang.InterruptedException

BRBrain

public BRBrain(java.io.File port)
        throws java.io.IOException,
               java.lang.InterruptedException

Same as BRBrain(String) but connect to CM-5 via a file instead of with RXTX.

Throws:
java.io.IOException
java.lang.InterruptedException
Method Detail

statusToString

public static final java.lang.StringBuffer statusToString(int status,
                                                          java.lang.StringBuffer buf)

Compose a human-readable string of CM-5 status from a CM-5 status byte.

Parameters:
status - the bitpacked status value
buf - the buffer to append, or null to make one
Returns:
the buffer to which the string was appended

statusToString

public static final java.lang.String statusToString(int status)
Covers statusToString(int, StringBuffer)


listPorts

public static java.io.PrintStream listPorts(java.io.PrintStream printStream)

Convenience method to query the list of available ports according to RXTX.

Parameters:
printStream - the stream on which to print the list, e.g. System.out
Returns:
printStream

listPorts

public static java.io.PrintStream listPorts()
covers listPorts(PrintStream), uses System.out


recover

public void recover()
             throws java.io.IOException,
                    java.lang.InterruptedException
waits RECOVER_MS and then drains recv buf

Throws:
java.io.IOException
java.lang.InterruptedException

drainFromCM5

protected void drainFromCM5()
                     throws java.io.IOException,
                            java.lang.InterruptedException
drain fromCM5

Throws:
java.io.IOException
java.lang.InterruptedException

setBaudRate

protected void setBaudRate(int baudRate)
                    throws java.io.IOException
attempt to set the baud rate, works only if using RXTX

Throws:
java.io.IOException

flashCM5

public int flashCM5(java.io.InputStream binary,
                    java.io.PrintStream log)
             throws java.io.IOException,
                    java.lang.InterruptedException

Interact with the user and the CM-5 bootloader to flash new firmware to the CM-5.

Parameters:
binary - an InputStream from which the new firmware binary is read
log - an output stream to which progress and prompt messages are displayed
Returns:
the number of bytes flashed, negative of that if verify failed
Throws:
java.io.IOException - if there was an input our output error
java.lang.InterruptedException - if there was a timeout

flashCM5

public int flashCM5(java.io.File binary,
                    java.io.PrintStream log)
             throws java.io.IOException,
                    java.lang.InterruptedException
covers flashCM5(InputStream, PrintStream)

Throws:
java.io.IOException
java.lang.InterruptedException

flashCM5

public int flashCM5(java.lang.String binary,
                    java.io.PrintStream log)
             throws java.io.IOException,
                    java.lang.InterruptedException
covers flashCM5(File, PrintStream)

Throws:
java.io.IOException
java.lang.InterruptedException

flashCM5

public int flashCM5(java.lang.String binary)
             throws java.io.IOException,
                    java.lang.InterruptedException
covers flashCM5(String, PrintStream), uses System.out

Throws:
java.io.IOException
java.lang.InterruptedException

pingDynamixel

public int pingDynamixel(int id)
                  throws java.io.IOException,
                         java.lang.InterruptedException

Issue BRBrain.Instruction.I_PING packet requesting ping of the indicated dynamixel.

Parameters:
id - the id of the dynamixel to ping in the closed interval [0, AXRegister.MAX_DYNAMIXEL_ID] or 255 to ping the CM-5 itself
Returns:
the CM-5 status and retry bytes as the 0th and 1st byte of the returned int
Throws:
java.io.IOException - if there was a communication error
java.lang.InterruptedException - if the calling thread was interrupted while waiting for response bytes from the CM-5

pingCM5

public int pingCM5()
            throws java.io.IOException,
                   java.lang.InterruptedException
covers pingDynamixel(int), uses id 255 to ping the CM-5 itself

Throws:
java.io.IOException
java.lang.InterruptedException

scan

public boolean[] scan(boolean[] dynamixels,
                      int maxID)
               throws java.io.IOException,
                      java.lang.InterruptedException

Scan for presence of dynamixels with IDs in the closed interval [0, maxID].

Parameters:
dynamixels - presence written here, (re)consed if null or too short
Returns:
the array of dynamixel presence
Throws:
java.io.IOException
java.lang.InterruptedException

scan

public boolean[] scan(int maxID)
               throws java.io.IOException,
                      java.lang.InterruptedException
covers scan(boolean[], int), always conses

Throws:
java.io.IOException
java.lang.InterruptedException

setReadFormat

public int setReadFormat(int[] id,
                         AXRegister[] start,
                         int[] num)
                  throws java.io.IOException,
                         java.lang.InterruptedException

Set the read format as described in the class header doc.

The format is both cached for further use on the host and is transmitted to the CM-5.

Parameters:
id - the id of each dynamixel to read, in order. The number of dynamixels in the read format is considered to be the number of contiguous valid dynamixel IDs (i.e. ids in the interval [0, AXRegister.MAX_DYNAMIXEL_ID]) starting with the zeroth entry in the id array. A copy is made.
start - the start register on each dynamixel in the read format, must either be length 1, implying same start reg for all dynamixels, or have at least as many non-null initial entries as the number of read dynamixels. A copy is made.
num - the number of registers to read on each dynamixel in the read format, must either be length 1, implying same num regs for all dynamixels, or have at least as many valid initial entries as the number of read dynamixels. A copy is made.
Returns:
the returned BRBrain.Instruction.I_STATUS byte from the CM-5
Throws:
java.lang.IllegalArgumentException - if the number of dynamixels in the format exceeds MAX_DYNAMIXELS, if a dynamixel ID is used more than once in the format, if the latter args are too short, if the number of registers is negative, or if the span of registers extends beyond the last register
java.io.IOException - if there was a communication error
java.lang.InterruptedException - if the calling thread was interrupted while waiting for response bytes from the CM-5

setWriteFormat

public int setWriteFormat(int[] id,
                          AXRegister[] start,
                          int[] num)
                   throws java.io.IOException,
                          java.lang.InterruptedException

Similar to setReadFormat(int[], brbrain.AXRegister[], int[]).

Throws:
java.lang.IllegalArgumentException - if any register block AXRegister.containsReadOnlyRegs(brbrain.AXRegister, int)
java.io.IOException
java.lang.InterruptedException

checkAXIDs

public static void checkAXIDs(int[] id,
                              int n)
verify the first n dynamixel ids in the given array are unique


checkAXIDs

public static void checkAXIDs(int[] id)
covers checkAXIDs(int[], int), checks all


setFormat

protected int setFormat(int f,
                        int[] id,
                        AXRegister[] start,
                        int[] num)
                 throws java.io.IOException,
                        java.lang.InterruptedException

Common impl of setReadFormat(int[], brbrain.AXRegister[], int[]) and setWriteFormat(int[], brbrain.AXRegister[], int[]).

Parameters:
f - the format
id - the dynamixel ids to set
start - the start regs to set, either length 1 and all start regs set the same or at least as long as the number of dynamixels in the format
num - the reg numbers to set, either length 1 and all start regs set the same or at least as long as the number of dynamixels in the format
Returns:
the CM-5 status
Throws:
java.io.IOException
java.lang.InterruptedException

getReadFormat

public int getReadFormat(int[] id,
                         AXRegister[] start,
                         int[] num)

Get a copy of the most recently setReadFormat(int[], brbrain.AXRegister[], int[]), see which.

Arg id must either be null or at least as long as the number of dynamixels in the format.

Args star and num must either be null, length 1 and all data in format equal, or at least as long as the number of dynamixels in the format.

Returns:
the number of dynamixels in the current read format

getNumReadDynamixels

public int getNumReadDynamixels()
get the number of dynamixels in the current read format


getTotalNumReadRegs

public int getTotalNumReadRegs()
get the total number of registers in the current read format


getWriteFormat

public int getWriteFormat(int[] id,
                          AXRegister[] start,
                          int[] num)

Get a copy of the most recently setWriteFormat(int[], brbrain.AXRegister[], int[]), see which.

Args handled similar to getReadFormat(int[], brbrain.AXRegister[], int[]).

Returns:
the number of dynamixels in the current write format

getNumWriteDynamixels

public int getNumWriteDynamixels()
get the number of dynamixels in the current write format


getTotalNumWriteRegs

public int getTotalNumWriteRegs()
get the total number of registers in the current write format


getFormat

protected int getFormat(int f,
                        int[] id,
                        AXRegister[] start,
                        int[] num)

Common impl of getReadFormat(int[], brbrain.AXRegister[], int[]) and getWriteFormat(int[], brbrain.AXRegister[], int[]).

Parameters:
f - the format
id - the dynamixel ids to get
start - the start regs to get, length 1 and all start regs same through format or length geq number of dynamixels in format
num - the reg numbers to get, length 1 and all start regs same through format or length geq number of dynamixels in format
Returns:
the number of dynamixels in the format

checkFmtSame

protected void checkFmtSame(AXRegister[] start,
                            int n)
ensure that all initial n elements of start are equal


checkFmtSame

protected void checkFmtSame(int[] num,
                            int n)
ensure that all initial n elements of num are equal


setReadFormat

public int setReadFormat(java.lang.Object[] args)
                  throws java.io.IOException,
                         java.lang.InterruptedException

Covers setReadFormat(int[], brbrain.AXRegister[], int[]), uses parseFormatArgs(java.lang.Object[]), for jscheme API convenience.

Throws:
java.io.IOException
java.lang.InterruptedException

setWriteFormat

public int setWriteFormat(java.lang.Object[] args)
                   throws java.io.IOException,
                          java.lang.InterruptedException

Covers setWriteFormat(int[], brbrain.AXRegister[], int[]), uses parseFormatArgs(java.lang.Object[]), for jscheme API convenience.

Throws:
java.io.IOException
java.lang.InterruptedException

parseFormatArgs

protected java.lang.Object[] parseFormatArgs(java.lang.Object[] args)

Parse read or write format from a contiguous array, for jscheme API convienience.

Parameters:
args - an integer multiple of <Integer, AXRegister, Integer> triples
Returns:
a three-element array consisting of an array of int, an array of AXRegister, and an array of int, giving the dynamixel id, start register and number of registers respectively in the format

getReadFormat

public java.lang.Object[] getReadFormat()

Covers getReadFormat(int[], brbrain.AXRegister[], int[]), uses packFormat(int, int[], brbrain.AXRegister[], int[]), for jscheme API convenience.


getWriteFormat

public java.lang.Object[] getWriteFormat()

Covers getWriteFormat(int[], brbrain.AXRegister[], int[]), uses packFormat(int, int[], brbrain.AXRegister[], int[]), for jscheme API convenience.


packFormat

protected java.lang.Object[] packFormat(int n,
                                        int[] id,
                                        AXRegister[] start,
                                        int[] num)

Pack read or write format from a contiguous array, for convienience of the scheme API.

Parameters:
n - the number of dynamixels in the format
id - the dynamixel ids
start - the start registers
num - the number of registers for each dynamixel
Returns:
a flat array containing n <Integer, AXRegister, Integer> triples giving the dynamixel id, start register, and number of registers for each dynamixel in the format

read

public int[] read()
           throws java.io.IOException,
                  java.lang.InterruptedException

Read int register values and CM-5 status into an array, for jscheme API convenience.

Returns:
an array of totalNumRegs[F_READ]+1 values, with the last set to the CM-5 status/retries
Throws:
java.io.IOException
java.lang.InterruptedException

readNatural

public float[] readNatural()
                    throws java.io.IOException,
                           java.lang.InterruptedException

Read natural register values and CM-5 status into an array, for jscheme API convenience.

Returns:
an array of totalNumRegs[F_READ]+1 values, with the last set to the CM-5 status/retries
Throws:
java.io.IOException
java.lang.InterruptedException

read

public int read(float[] data)
         throws java.io.IOException,
                java.lang.InterruptedException

Read data from dynamixels in natural units according to the current read format.

Parameters:
data - the read data is stored here, must have at least as many entries as the total number of registers in the current read format. If there were problems reading any particular bytes they will be returned as 0xff.
Returns:
the CM-5 status and retry bytes as the 0th and 1st byte of the returned int
Throws:
java.io.IOException - if there was a communication error
java.lang.InterruptedException - if the calling thread was interrupted while waiting for response bytes from the CM-5

read

public int read(int[] data)
         throws java.io.IOException,
                java.lang.InterruptedException
same as read(float[]) but reads register ints directly

Throws:
java.io.IOException
java.lang.InterruptedException

read

protected int read(java.lang.Object data)
            throws java.io.IOException,
                   java.lang.InterruptedException
common impl of read(float[]) and read(int[])

Throws:
java.io.IOException
java.lang.InterruptedException

updateCachedValue

protected void updateCachedValue(int axID,
                                 AXRegister register,
                                 int value)
update cache


getCachedValue

public BRBrain.CachedValue getCachedValue(int axID,
                                          AXRegister register)

Look up the most recent BRBrain.CachedValue of of the specified reg, null if none.


write

public int write(float[] data)
          throws java.io.IOException,
                 java.lang.InterruptedException

Write data to dynamixels in natural units according to the current write format.

Parameters:
data - the data to write, must have at least as many entries as the total number of registers in the current write format
Returns:
the CM-5 status and retry bytes as the 0th and 1st byte of the returned int
Throws:
java.io.IOException - if there was a communication error
java.lang.InterruptedException - if the calling thread was interrupted while waiting for response bytes from the CM-5

write

public int write(int[] data)
          throws java.io.IOException,
                 java.lang.InterruptedException
same as write(float[]) but writes register ints directly

Throws:
java.io.IOException
java.lang.InterruptedException

write

public int write(java.lang.Object data)
          throws java.io.IOException,
                 java.lang.InterruptedException
common impl of write(float[]) and write(int[])

Throws:
java.io.IOException
java.lang.InterruptedException

setTimeoutMS

public double setTimeoutMS(double timeoutMS)
set the timeout for a response from the CM-5 in ms, returns old value


getTimeoutMS

public double getTimeoutMS()
get the current timeout for a response from the CM-5 in ms


recvByte

protected int recvByte(boolean addToChecksum)
                throws java.io.IOException,
                       java.lang.InterruptedException

Receive a byte from the CM-5.

Parameters:
addToChecksum - whether to add the value of the received byte to the current checksum in progress
Returns:
the received byte
Throws:
java.io.IOException - if there was a communication error
java.lang.InterruptedException - if the calling thread was interrupted while waiting for response bytes from the CM-5

dbg

protected void dbg(java.lang.String msg,
                   int b)
print a debug message for a byte


recvByte

protected int recvByte()
                throws java.io.IOException,
                       java.lang.InterruptedException
covers recvByte(boolean), always adds to checksum

Throws:
java.io.IOException
java.lang.InterruptedException

sendByte

protected void sendByte(int b,
                        boolean addToChecksum)
                 throws java.io.IOException

Send a byte to the CM-5.

Parameters:
b - the byte to send
addToChecksum - whether to add the value of the sent byte to the current checksum in progress, after sending the byte
Throws:
java.io.IOException - if there was a communication error

sendByte

protected void sendByte(int b)
                 throws java.io.IOException
covers sendByte(int, boolean), always adds to checksum

Throws:
java.io.IOException

startSendPacket

protected void startSendPacket(BRBrain.Instruction instruction)
                        throws java.io.IOException
start an outgoing packet with the given instruction

Throws:
java.io.IOException

endSendPacket

protected void endSendPacket()
                      throws java.io.IOException
end an outgoing packet, sending checksum

Throws:
java.io.IOException

startRecvPacket

protected void startRecvPacket(BRBrain.Instruction instruction)
                        throws java.io.IOException,
                               java.lang.InterruptedException
start an incoming packet expecting the given instruction

Throws:
java.io.IOException
java.lang.InterruptedException

endRecvPacket

protected void endRecvPacket()
                      throws java.io.IOException,
                             java.lang.InterruptedException
end an incoming packet, validating checksum

Throws:
java.io.IOException
java.lang.InterruptedException

recvStatus

protected int recvStatus()
                  throws java.io.IOException,
                         java.lang.InterruptedException
receive a BRBrain.Instruction.I_STATUS packet, return payload

Throws:
java.io.IOException
java.lang.InterruptedException

recvADCs

protected void recvADCs()
                 throws java.io.IOException,
                        java.lang.InterruptedException
receive and store the ADC channel readings in adcValue

Throws:
java.io.IOException
java.lang.InterruptedException

adcToVolts

public static float adcToVolts(int value)
convert a raw ADC reading to V at the input of the 3.3k/10k divider


getADC

public int getADC(int channel)
get the most recent ADC reading for the given channel


close

public void close()
close the serial port, no further comms possible


finalize

protected void finalize()
close()s

Overrides:
finalize in class java.lang.Object

verifyStatus

public static boolean verifyStatus(int status,
                                   java.lang.String operation,
                                   boolean warnOnly)
                            throws java.io.IOException

Verify a CM-5 return status code/retry count.

Emits a warning message on stderr if the retry count is non-zero, but only throws an exception when the status code is non-zero.

Parameters:
status - the CM-5 return status code/retry count
operation - a string describing the operation for which the status applies
warnOnly - if set then a warning msg is printed instead of any exception
Returns:
true if status was ok
Throws:
java.io.IOException - if not warnOnly and the status code, but not necessarily the retry count, is non-zero

verifyStatus

public static void verifyStatus(int status,
                                java.lang.String operation)
                         throws java.io.IOException
covers verifyStatus(int, String, boolean), not warn

Throws:
java.io.IOException

dup

public static int[] dup(int[] from,
                        int[] to,
                        int n)
duplicate first n element of from into to, reallocating as necessary


dup

public static int[] dup(int[] from,
                        int[] to)
covers dup(int[], int[], int), copies all


dup

public static boolean[] dup(boolean[] from,
                            boolean[] to,
                            int n)
duplicate first n element of from into to, reallocating as necessary


dup

public static boolean[] dup(boolean[] from,
                            boolean[] to)
covers dup(boolean[], boolean[], int), copies all


dup

public static java.lang.String[] dup(java.lang.String[] from,
                                     java.lang.String[] to,
                                     int n)
duplicate first n element of from into to, reallocating as necessary


dup

public static java.lang.String[] dup(java.lang.String[] from,
                                     java.lang.String[] to)
covers dup(String[], String[], int), copies all


ensureCapacity

public static int[] ensureCapacity(int[] a,
                                   int n)
make sure a is at least length n


ensureCapacity

public static boolean[] ensureCapacity(boolean[] a,
                                       int n)
make sure a is at least length n


ensureCapacity

public static java.lang.String[] ensureCapacity(java.lang.String[] a,
                                                int n)
make sure a is at least length n