march_hardware

Overview

The march_hardware package is a C++ library to interact with the physical MARCH exoskeleton. Its goal is to provide an api for actuating the exoskeleton without knowledge of the underlying hardware.

Class Structure

Tip

The march_hardware_builder can help with the class structure of the hardware package, especially when looking at an example yaml <march_hardware_builder/robots/march4.yaml>.

The highest level class is the MarchRobot, it contains a list of Joints, which can be accessed. Each Joint is identified by a name and optionally has an IMotionCube and TemperatureGES. This is enough knowledge to start interacting with the robot.

Example usage

Here is an example of the commands you can use on a MarchRobot object when it is created with the correct joints.

MarchRobot robot;  // This step should use the hardware builder, but uses this to simplify the example
robot.startEthercat();
Joint& right_knee = robot.getJoint("right_knee");
right_knee.prepareActuation();
right_knee.actuateRad(0.2);
double angle = right_knee.getAngleRadAbsolute();
float temperature = right_knee.getTemperature();
robot.stopEthercat();

EtherCAT

EtherCAT is the fieldbus protocol used to communicate with the local hardware (‘slaves’) in the exoskeleton. SOEM (short for Simple Open EtherCAT Master) is a C library which provides most EtherCAT functionalities. As said, the hardware package is mainly a class structure on top of SOEM functioning as an api for controlling the exoskeleton. The interfaces can be roughly divided into three parts:

  • EthercatMaster

  • PDO messages

  • SDO messages

EthercatMaster

The EthercatMaster class contains the main EtherCAT functionality and the main interface with SOEM. EtherCAT can be started and stopped via the EthercatMaster. When EtherCAT is started, a parallel thread is started that continuously sends and receives the latest EtherCAT PDO data and monitors if all slaves are still present and operational. When EtherCAT is stopped, this parallel thread stops running.

The EthercatMaster class expects several arguments in its constructor: the network interface name (ifname) of your device, the number of EtherCAT slaves in your robot, and the cycle time of the EtherCAT thread in milliseconds. An example is provided below.

EthercatMaster ethercat("enp2s0", 14, 2); // 14 slaves, 2 ms cycle time

Tip

Find out the ifname of your device by running ifconfig in a terminal.

PDO messages

Process Data Objects (PDOs) are the cyclic and continuous type of messages of EtherCAT, and the main form of exchanging data with the slaves. Reading and writing EtherCAT PDO messages is possible through the other classes in the march_hardware package (e.g. Joint, IMotionCube, Encoder, PowerDistributionBoard). For example, the Encoder class <march_hardware/include/march_hardware/encoder/encoder.h> getAngleIU() function reads and returns the latest encoder value that was received by the EthercatMaster. Functions such as getAngleIU() all call the same generic interface for reading from and writing to slaves. The generic interface is defined in pdo_interface.cpp <march_hardware/include/march_hardware/ethercat/pdo_interface.h>.

Note

When reading or writing PDO messages over EtherCAT via SOEM, you need three things:

  • The index of the slave you want to read from or write to.

  • The amount of bytes you want to read or write.

  • The byte offset of the data you want to read or write for a particular slave.

The byte offsets need to correspond with how the slave is configured. For GES and PDB slaves, this is stored in the EEPROM of the slave. For the IMotionCube, this is configurable during startup through a process called PDO mapping.

SDO messages

Service Data Objects (SDOs) are non-cyclic EtherCAT messages. They are used for sending one-time messages, for example when initializing an IMotionCube. The generic SDO interface can be found in sdo_interface.h <march_hardware/include/march_hardware/ethercat/sdo_interface.h>.

Power Distribution Board

The PowerDistributionBoard class contains all functionality for communicating with the Power Distribution Board over EtherCAT. For example, high voltage nets can be turned on and off via this class, and the currents that the Power Distribution Board measures can be read. The PowerDistributionBoard class contains a HighVoltage and a LowVoltage class which contain methods for controlling the high voltage and low voltage nets.

PowerDistributionBoard pdb;
float current = pdb.getPowerDistributionBoardCurrent();
pdb.getHighVoltage().setNetOnOff(true, 2); // Turn on net 2

Note

The PowerDistributionBoard constructor requires EtherCAT byte offsets as arguments. These need to be specified in the robot description yaml files of the hardware_builder package.

Note

The functionality of the PowerDistributionBoard is highly dependent on the software running on the LPC1768 of the Power Distribution Board. See the ethercat-slaves repository <src/pdb> for the LPC1768 code.

Exceptions

Because safety is very important, the march_hardware package will throw an exception whenever it encounters something that should not happen. The march_hardware package implements custom exceptions in the error module <march_hardware/include/march_hardware/error> with error types for different situations. See Error Codes for all types of errors and how to possibly fix them. When such an exception occurs, the high voltage is turned off and the exoskeleton will stop moving.

ROS API

The hardware package is written without depending on ROS to ensure that it can remain functional even when ROS will no longer be used. The package does depend on ROS for logging, but that can be easily changed if needed.