## Core Concepts

This section contains background of concepts that are common across all of HEBI’s hardware and software products. As much as possible, information here is presented in a general form while more hardware-specifc or language-specific details are provided, respectively, in the Hardware and Tools/APIs sections.

## Modules

### Communications

Modules are connected to host computers via standard Ethernet and standard commercially available networking equipment. In an Ethernet network every client needs to obtain an IP address in order to communicate. There are two ways to get an IP address:

 For normal use, we recommend that you use dynamic address assignment. This requires you to plug-in your computer and the modules into a router that supports DHCP. New modules ship configured for DHCP by default.

If your network does not already have a router, or if your network enforces security policies that do not allow unregistered devices on the network, we recommend that you purchase a router. Virtually all consumer-grade routers have DHCP enabled by default, so a quick search on your shop of choice (e.g. Amazon) for "Router" should work. Some examples are listed below:

• Mikrotik RB750Gr2

1. Plug the computer as well as your module(s) into the same router as shown below. You can daisy-chain multiple modules or extend the network using a Switch.

2. Power on the modules and look at the LED color. Fading orange/blue means that it is searching for an IP address. Once it turns into a blue fade, the modules has obtained an IP address.

3. You can check whether communications have been setup correctly by running the Scope GUI or any of our APIs.

IP addresses can be set statically so that modules don’t need to query for an address every time. This can sometimes be useful when it is difficult to integrate a DHCP server or if the robot needs to initialize quickly.

Static IP addresses can be set by right-clicking on a module’s entry in the Scope GUI as highlighted below. Note that this requires an initial dynamic address in order to communicate.

This will open the following dialog that allows for setting the IP address and subnet mask. The values default to the device’s current address. For more information on what values to set, please refer to Understanding TCP/IP addressing and subnetting basics.

You can revert to dynamic addressing by calling "clear address" in the same menu as "set address" or by doing a hardware reset using the following procedure:

1. Press the hardware reset button

2. Restart the module (e.g. by turning power off and on again). The LED should start fading red

3. Wait until the LED does a faster-blink red and let go of the reset button

4. Restart the module again

#### Connections to Multiple Networks

Control computers may have more than one network interfaces and be connected to more than one network. For example, computers can be on wired Ethernet and WiFi at the same time. In order to find modules on all networks, the default behavior for the HEBI module lookup is to broadcast on all interfaces.

 Note that in some tools and APIs the local networks may be determined only once on startup, so changing your network, e.g., plugging your computer into a different router, may require a restart of the tool or API.

#### Example Robot / Network Configurations

There a number of different ways you can configure the network between the computers and the modules, depending on the needs of your application. Below are a number of different setups that we have made for various robots.

 To view a larger version of the diagrams below, right-click the image and open in a new tab.
Summary / Description Diagram

Office Network w/ DHCP
The robot shares the same standard wired office network that is used by the development computer. This is probably the simplest setup.

Office Network w/ DHCP + Wireless Bridge
The robot shares the same office network that is used by the development computer, except the connection to the robot is over a wireless bridge. This provides the convenience of not needing to run a wired connection to the router, with the drawback of the lower reliability of a wireless communication. Feasibility will depend on your application.

Office Network w/ DHCP + Dedicated Wireless Bridge
Same as above with the addition that the connection to the robot is over a dedicated point-to-point wireless connection with no other wireless network traffic. When configured for low-latency wireless standards, e.g. 802.11a or 802.11ad, this can provide a very reliable wireless connection.

Robot Network w/ Static IP
The robot modules are configured with static IP addresses and connect to the development computer using a separate network interface from the office network (e.g., using the computer’s wired network interface for the robot and using the wireless interface for the office network / internet). This has the advantage of separating robot network traffic from the office network.

Robot Network w/ Static IP + Dedicated Wireless Bridge
The robot modules are configured with static IP addresses and connect to the development computer using a separate network interface from the office network, and the connection to the robot is over a dedicated point-to-point wireless connection with no other wireless network traffic. When configured for low-latency wireless standards, e.g. 802.11a or 802.11ad, this can provide a very reliable wireless connection.

Robot Network w/ DHCP
The robot modules are on a network with its own router configured for DCHP, and they connect to the development computer using a separate network interface from the office network. The WAN port of the robot network’s router can optionally be plugged into the office network to provide an internet connection.

Robot Network w/ DHCP + Wireless Bridge
The robot modules are on a network with its own router configured for DCHP, and they connect to the development computer using a separate network interface from the office network. The WAN port of the robot network’s router can optionally be plugged into the office network to provide an internet connection. This provides the convenience of not needed to run a wired connection to the router, with the drawback of the lower reliability of a wireless communication. Feasibility will depend on your application.

Robot Network w/ DHCP + Dedicated Wireless Bridge
Same as the configuration above, except he connection to the robot is over a dedicated point-to-point wireless connection with no other wireless network traffic. When configured for older low-latency/lower-bandwidth wireless standards, e.g. 802.11a, this can provide a very reliable wireless connection.

Robot Network w/ DHCP + On-Board Computer
The robot modules are on a wired network with its own router configured for DCHP, and there is a dedicated on-board computer. This provides a reliable control computer for mobile applications. Development can be done off-board using a wired connection to either the robot network or office network. This can be done without a switch, daisy-chaining thru the modules with the access point / router on one end of the chain and the on-board computer on the other.

Robot Network w/ DHCP + On-Board Computer + Switch
Same as the configuration above, with the additon of a switch on-board to provide more flexible routing and easy access to additional wired connections for expansion and development. This is the configuration of the Modular Chassis Kits

### Power

Modules run on DC voltages between 24V-48V. The internal electronics of the modules are designed to properly regulate and automatically scale motor control parameters as the bus voltage changes.

However, if actuators are heavily loaded and are being back-driven or impacting the world with significant amounts of force there may be voltage spikes as energy is sent from a back-driven actuator out into the power system. In these cases we recommend using a shunt regulator, or using a large battery system that can absorb these effects.

### Firmware Modes

Modules contain two separate sets of firmware. When powering up or restarting, a device initially starts in a Bootloader mode that initializes the IP address, offers diagnostic features, and allows for safe firmware upgrades. In bootloader, the status LED will blink blue-yellow until the module has been assigned an IP address. Once it has an IP address the status LED will change to a blue on/off fade.

After a fixed period of time, or on request from the Scope GUI or a command from the API, the module boots into the Application mode, which initializes all local device drivers, accepts commands, and responds to requests to feedback. When the module enters application mode the status LED will change to a slow green fade.

### LED Status Codes

The Status LED is a multi-color indicator that provides information about the current state of a module, detailed in the table below. It is located under the white plastic window on the side of the module near the connector. There is also a smaller white LED to the left of the Status LED that indicates that module is receiving power.

#### Normal Statuses

The following LED statuses are displayed during normal operation, and common fault or safety modes.

LED Pattern Meaning

Not yet obtained an IP address. By default, this is the status of a module when resetting or powering up. After the module receives and IP address, typically after a few seconds, the status LED will change to a Green Slow Fade (see below).

Note: For a module to receive an IP address it needs to be on a local network with a router running DHCP.

Note: If a module remains in this mode for more than a few minutes without a network connection, and then a network connection is established, the module may not receive an IP address. Restarting the module with an established network connection will solve this issue.

Operating normally, not receiving any commands.

Note: If a module has a manually assigned IP address it will start directly into this mode when resetting or powering up.

Operating normally, acting on received commands.

M-stop triggered.

Module output is at a mininum or maximum position limit.

If a module boots up and it is outside a position limit, commands will be disabled until the module moved manually inside the limit. If a new joint limit is set and the module is outside the new limit, commands will be disabled until the module moved manually inside the limit.

Once a module is inside the position limit (status LED changes to a green fade), if it moves back out of the limit it will still accept commands as long as the commands move the position away from the limit.

Motor winding temperature is high, and the motor’s power is being limited by an internal safety controller to less than what is currently being commanded.

#### Abnormal Statuses

LED Pattern Meaning

Operating normally, but effort (torque) sensing has not been calibrated.

Yellow Solid On

Module electronics above safe temperature.

Red Solid On

If encountered immediately after exiting the bootloader, the module does not have application firmware. Use the Scope GUI to install new firmware.

If encountered while the module is running normally, the motor winding temperature is above a critical value and power to the motor has been shut off.

Current sensing is not calibrated. The module’s motor will drive in this mode.

Position sensing is not calibrated. The module’s motor will only drive in `Direct PWM` mode.

No Light

There is a problem with the module.

The following LED statuses are displayed during normal operation when a module is restarted into bootloader mode, which allows the firmware of the module to be updated. Entering this mode, updating, and rebooting is typically handled automatically by Scope.

LED Pattern Meaning

Not yet obtained an IP address.

Note: For a module to receive an IP address it needs to be on a local network with a router running DHCP.

Note: If a module remains in this mode for more than a few minutes without a network connection, and then a network connection is established, the module may not receive an IP address. Restarting the module with an established network connection will solve this issue.

Obtained an IP address. The Scope GUI or APIs can be used to keep the module in Bootloader Mode on restart.

Note: If a module has a manually assigned IP address it will start directly into this mode when resetting or powering up.

## Groups

Groups are the way you communicate with modules when using the programming APIs. It allows one or more modules to be treated as one coordinated system in terms of feedback and control. Modules in a group don’t need to be a physically connected "robot". Any modules that are one the same network can be part of a group.

### Creating Groups

You create a `Group` using a `Lookup` to see what’s on the network. You can adjust settings like the `CommandLifetime` and `FeedbackFrequency`.

Once one or more modules are turned on and plugged into the network they can be discovered by a `Lookup` that periodically sends broadcast messages on the network. The interval is configurable and by default is set to 5 Hz. Each module has a user-settable `Name` and `Family` to help better organize a system on the network. These can be set from the APIs or by right-clicking modules in the left panel in the Scope GUI.

Discovered modules can be combined into a `Group` that provides a basic way to send commands and retrieve feedback. Groups also handle higher-level issues such as data synchronization and logging. You can also request `Info` from the modules in a group.

Each module has multiple keys that can be used to identify a module on a given network:

• `Family` (human settable, e.g., "RobotArm_6DoF")

• `Name` (human settable, e.g., "base" or "elbow")

• `IP address` (network unique)

• `MAC address` (global unique)

There are no software limits on the number of active groups, the number of modules within a group, or the number of groups that a module is part of. Groups are the only way to communicate with modules using the APIs. Even if you are working with a single module, you will need to create a group for that module.

### Feedback

You get synchronized `Feedback` from a `Group`. Once a `Group` is created, feedback requests automatically go out to all the individual modules and actuators in the group at the `FeedbackFrequency` and get organized by the API into vectors, matrices, and structures of data corresponding to all the feedback from a single point in time.

You can view the most recent feedback for a group at any time by getting the `NextFeedback` for the group. The details of how `NextFeedback` is returned are API-dependent.

The table below lists the most common items that can be returned as feedback from HEBI hardware modules. Note that not all modules or actuators will support all the items listed below. There are additional feedback items specific to paricular hardware that is detailed in the Hardware section.

• X-Series Actuator

• I/O Board

Parameter Units Description

`time`

`sec`

The current time from the system clock used by the API. This is a single value that corresponds to all feedback at this timestep.

`pcRxTime`

`sec`

The system time when feedback was received by each module. The most recent of these times is what is reported as the single `time` above.

`pcTxTime`

`sec`

The system time when feedback requests were sent to each module.

`hwRxTime`

`sec`

The hardware timestamp when each module in the group transmitted its feedback. Time initializes at 0 when a module is powered on.

`hwTxTime`

`sec`

The hardware timestamp when each module in the group received a request for feedback. Time initializes at 0 when a module is powered on.

`position`

`rad` or `m`

Sensed position (absolute) of the output of an actuator.

`velocity`

`rad/sec` or `m/sec`

Sensed velocity at the output of an actuator.

`effort`

`Nm` or `N`

Sensed force or torque (absolute) at the output of an actuator.

`positionCmd`

`rad` or `m`

The currently commanded position. If no position is being commanded a value of `NaN` is returned.

`velocityCmd`

`rad/sec` or `m/sec`

The currently commanded velocity. If no velocity is being commanded a value of `NaN` is returned.

`effortCmd`

`Nm` or `N`

The currently commanded force or torque, or if in `DIRECT_PWM` mode, the commanded `PWM` to an actuator’s motor. If no effort is being commanded a value of `NaN` is returned.

`accel` or `accelX` `accelY` `accelZ`

`m/sec^2`

A module’s sensed 3-DoF acceleration from an internal IMU, including gravity. Depending on the API, XYZ values are combined together into a single vector or returned individually.

`gyro` or `gyroX` `gyroY` `gyroZ`

`rad/sec`

A module’s sensed 3-DoF angular velocity from an internal IMU. Depending on the API, XYZ values are combined together into a single vector or returned individually.

`motorCurrent`

`A`

The amount of current an actuator’s motor draws at the bus voltage.

`windingCurrent`

`A`

The amount of current draw of the windings of an actuator’s motor.

`voltage`

`V`

The sensed bus voltage into the module.

`motorTemperature` `ambientTemperature` `processorTemperature` `actuatorTemperature` `windingTemperature`

`deg-C`

Various internal temperatures reported from the module.

`ledR` `ledG` `ledB`

`0 to 1`

RGB color values of the status LED.

### Commands

You can send `Commands` to a group, typically desired `position`, `velocity`, and `effort` commands for actuators to execute. These commands are targets for low-level controllers that run on an actuator. Commands are typically sent from a loop that runs around 100 Hz, but you can run faster (up to 1kHz) or slower depending on the needs of your application. Generating smooth commands to go from one position to another can be accomplished the Trajectory API.

Parameter Units Description

`position`

`rad` or `m`

The desired position of the output of an actuator.

`velocity`

`rad/sec` or `m/sec`

The desired velocity of the output of an actuator.

`effort`

`Nm` or `N`

The desired torque or force of the output of an actuator. For an actuator in`DIRECT_PWM` control strategy, this will be the desired `PWM` of the motor, from `-1 to 1`.

For safety, each command has a `CommandLifetime`. This is the maximum duration that a command may be active before it expires. If the hardware does not receive further commands within the specified time frame, all local controllers get deactivated. This is similar to a safety feature that many industrial robots have that requires users to send at least one update every interval (e.g. 5 ms) to keep the robot from turning off and locking up. Since the timeout deadline depends heavily on the application, we chose to implement the inverse approach in which every command specifies its own lifetime.

Additionally, moudles do not accept commands from any other sources during the lifetime of a command. This lock-out mitigates the risk of other users accidentally sending conflicting targets (e.g., by dragging slider in the Scope GUI). The default command lifetime in all APIs is `0.25 sec`. You can set `CommandLifetime` to be any value greater than `0`. Setting `CommandLifetime` to `0` is a special case that disables it. This means that commands sent once will be active on a module indefinitely, and that a module will also accept commands from other sources, since there is no lock-out.

While the timeout can be deactivated, we strongly recommend to make use of this feature. Otherwise, the hardware will continue to execute the last sent command indefinitely, which can result in unwanted behavior, especially when commanding velocities and efforts (torques). Alternatively, we recommend using a hardware button that triggers a motion stop ("M-Stop").

 Note that the command lifetime is a common source of confusion for new users. If commands are only sent once, or if your program pauses for longer than `CommandLifetime` between sending commands, a module will stop until a new command is sent. In normal use of the API commands should be sent in a loop, typically around 100 Hz.

### Logging

You can log feedback automatically in the background at the group’s `FeedbackFrequency`. These logs can be loaded into memory or converted into different formats for use with other tools. Each `Group` can be generating one log at a time. It is possible (and often useful) to have more than one group simultaneously gathering feedback and/or logging from the same modules.

Logs are stored in a binary format and by default are labeled with a `.hebilog` file extension. Logging begins with a `startLog` call that returns the path to the `.hebilog` file and ends with a `stopLog` call. Calling `startLog` on a group that is already logging will immediately stop the current log and start a new one. Each API has tools that can load and parse logs into organized formats.

### Settings and Info

You can also use the APIs to set a number of different module-specific parameters, such as `Gains` and `Safety Limits`. See the Hardware Documentation for more detail.

## Motion Control

HEBI actuator modules can be controlled using position, velocity, and effort (typically torque). This section discusses the details of how these different inputs can be controlled and tuned for specific applications. Typically, the best performance can be achieved by coordinating and controlling a combination of commanded positions, velocities, and effort. The plots above show the difference between a poorly tuned controller (left) and a well-tuned controller (right) tracking the same desired commands.

### Control Strategies

Position, velocity, and effort controllers can be run individually or in any combination simultaneously. To combine these control inputs, PID control loops are used on position, velocity, and effort. These controllers can be cascaded and combined in different preset configurations, termed Control Strategies.

The active Control Strategy and its corresponding parameters can be set using:

 Changes to the active control strategy on an actuator do not automatically get persisted and will revert back to their orignal values after a rebooting a module. Settings on a module can be persisted by right-clicking the actuator in the Scope GUI or via the `persist` command in the various APIs.

#### Off

The motor is turned off. The actautor will not respond to commands of any kind.

#### Direct PWM (Strategy 1)

The effort command directly sets the motor `PWM`, from `-1 to 1`. This controller uses no feedback from the sensors in the actuator. The controller does not compensate for changes in the supplied voltage. All safety controllers to protect the actuator (temperature, velocity, joint limits, etc.) are still applied.

#### Strategy 2

Position and Velocity PID outputs sum with a feed-forward effort signal to generate an intermediate effort signal. This intermediate effort signal is then passed through an "inner" Effort PID controller which generates motor PWM commands.

#### Strategy 3

Position, Velocity, and Effort PID controllers all directly sum to generate motor PWM commands.

#### Strategy 4

Position PID output sums with a feed-forward Effort signal to generate an intermediate Effort signal. This intermediate effort signal is then passed through an "inner" Effort PID controller. The PWM output of the inner Effort controller is added to a Velocity PID controller output to generate motor PWM commands.

#### Choosing a Control Strategy

Different control strategies have different advantages depending on the application. It can be difficult to say which control strategy is best, since overall performance depends heavily on the tuning of the gains within a given control strategy. Often two different control strategies can be tuned to perform equally well for a given application.

As a rule of thumb, Strategy 3 or Strategy 4 are usually the best choices for beginning the process of gain-tuning. In both of these strategies the velocity contoller feeds directly to motor PWM. Because of this, the velocity PID loop can apply a feedforward PWM to the motor based on the desired velocity and the known actuator parameters. This generally allows Strategy 3 and Strategy 4 to have better velocity control with lower `Kp` gains than Strategy 2.

Strategy 3 is a good starting point for control if:

• You are primarily concerned with position and velocity control. The accuracy of the effort (torque) sensing does not directly effect the quality of the control, since the outputs of both the position and velocity PID controllers go directly to motor PWM.

• You are new to the field of contol or actuation. Since all the individual PID contollers sum directly on PWM, gain tuning is a little more intuitive.

• You are not relying heavily on effort control compared to position / velocity control. If you are relying on the commanded effort to improve the tracking of some aspect of a system (e.g. motor torques being commanded based on an impedance controller on the end effector of an arm), then the effort controller can sometimes 'fight' the position controller in ways that sometimes are not as intuitive as Strategy 4.

Strategy 4 is a good starting point for control if:

• You are using significant amounts effort control compared to position / velocity control. If you are relying on the commanded effort to improve the tracking of the actuator (e.g. motor torques being commanded based on an impedance controller on the end effector of an arm), then having the efforts sum before going to the effort PID controller can often result in more intuitive behavior when the position and effort commands 'disagree'.

• You want the position controller to act as much as possible as a linear spring. Since the position PID controller feeds to an inner effort controller (i.e. a torque controller) much more of the friction and drag of actuator’s geartrain is cancelled out, compared to Strategy 3. This can result in the actuator feeling more responsive to interference from the outside world (e.g. an arm bumping into a table or interacting with a person guiding it).

Strategy 2 is good for control if:

• You want the velocity controller to act as much as possible as a linear damper (viscous damping). At HEBI, we have generally not favored this control strategy for most applications because the noise in the velocity feedback signal makes for poor control when resulting effort command from the velocity PID controller is fed to the effort controller.

Direct PWM is good for control if:

• You want to run your own position / velocity / effort control at the API level in a way that isn’t satisfied by the built-in controllers on the actuator or module. It is also useful for system identification of the actuator or debugging purposes, since it elimates all feedback control within a module.

### Safety Controllers

In all of the control strategies, a series of safety controllers run after the calculation of the final PWM values (the 'Motor PWM' value in the control strategy diagrams above). These safety controllers will potentially modify the PWM value based on things like the bus voltage, motor winding temperature, motor velocity, and position limits.

The diagram below shows the priority in which the safety controllers run. Safety ontrollers that are applied later in the chain (further to the right in the diagram) take priority over safety controllers that are applied earlier (further to the left). Some of these safety controllers are parameterized and can be set by the user, such as the position safety limits. Other controllers, such as the voltage limit and motor temperature limits, are fixed and are set specifically for a certain type of hardware.

### Parameters and Gains

Each controller for position, velocity, and effort is a full PID controller that exposes gains for tuning the proportional, integral, and derivative response of the control loop. Additionally, there are are number of other parameters that can be used to modify the response of the loop (see table below), threshold and low-pass the input and output, limit integral windup, set a deadzone region, and provide feedforward commands where appropriate.

A diagram showing the effect of min/max output limits, deadzone, and punch parameters on a standard proportional controller (P-controller) is shown below.

#### Description of Parameters

The table below lists the parameters that are common to each of the individual position, velocity, and effort PID-controllers. The API-specific information for each parameter are detailed in the next section.

The gains and control parameters on a module can be set using:

 Changes to the gains on an actuator do not automatically get persisted and will revert back to previously persisted values after a reboot. Gains and other module parameters can be persisted by right-clicking the actuator in the Scope GUI or via the `persist` command in the various APIs. Persisting will retain only the gains that are currently active. For example, if you set gains in Strategy 3, then switch to Strategy 4 and change the gains, and then 'Persist', only the changed gains in Strategy 4 will get persisted and the changes to the gains in Strategy 3 will be lost.
Parameter Description Units

`Kp`

The proportional gain of a standard PID-controller. The role of this term is to act like a linear spring and provide an output proportional to the measured error.

`(PWM / unit_error)` or `(effort / unit_error)` depending on the Control Strategy

`Ki`

The integral gain of a standard PID-controller. The role of this term is to accumulate past errors to help eliminate steady-state error.

`(PWM / (unit_error x sec))` or `(effort / (unit_error x sec))` depending on the Control Strategy

`Kd`

The derivative gain of a standard PID-controller. The role of this term is to damp the error based on its velocity.

`(PWM / (unit_error / sec))` or `(effort / (unit_error / sec))` depending on the Control Strategy

`Feedforward (FF)`

Feedfoward gain that is multiplied to the input value. If the PID controller is a velocity or effort controller that outputs `PWM` (all the effort PID controllers and the velocity PID controllers in Strategy 3 or Strategy 4) this gain is normally set to 1. Otherwise the gain should generally be set to 0.

(`PWM / unit_error`), on controllers where feedfoward is used

`Deadzone (Dz)`

Area around zero where the output of the PID loop is modified to reduce its output. The deadzone will shift the effect of `Kp` so that the zero-`effort` or zero-`PWM` intercept will be at +/- the deadzone value. `Ki` is modified so that it does not integrate any additional error inside the deadzone, but any accumulated error will remain. `Kd` is modified to be `0` inside the deadzone. `Feedforward` terms will still apply inside the deadzone.

`(unit_error)`

`I Clamp`

Maximum value that `Ki` is allowed to wind up. A value of `0` will disable the integral term. Values of `+/-inf` can be used to remove any windup limits.

`(PWM or effort)` depending on the Control Strategy

`Punch`

A step amount that can be added to the standard proportional gain that can sometimes be useful in overcoming motor stiction.

`(PWM or effort)` depending on the Control Strategy

`Min/Max Target`

Threshold values for the input to the PID controller.

`(unit_error)`

`Min/Max Output`

Threshold values for the output to the PID controller.

`(PWM or effort)`

`Target LP`

A IIR low-pass filter applied to either the input to the PID controller.

`(0 to 1)`, where `1` is no low-passing and smaller values more heavily low-pass the input to the controller.

`Output LP`

A IIR low-pass filter applied to either the output of the PID controller.

`(0 to 1)`, where `1` is no low-passing and smaller values more heavily low-pass the output from the controller.

`D on error`

Flag for whether `Kd` runs on the derivative of the output of the PID controller or the error of the PID controller (the difference of the target and output values).

`(true or false)`

#### Tuning Controller Gains

Performance of an actuator or an overall robot depends heavily on the settings of the controller parameters, or 'tuning the gains'. HEBI actuators ship with a set of default gains that allows the actuator to run well under light loads, but if a significant load or inertia is added to the actuator’s output the gains that are needed for good control will likely change.

For some single-DOF systems there are a variety of standard gain-tuning techniques can possibly be applied. Finding 'good gains' for something as complex as a full robot depends on the details of the desired application. For new multi-DOF systems it is difficult to predict ahead of time how the gains will need to be tuned. However, there are some rules of thumb:

• Lower is better. If a system can perform well with lower gains, that is often preferable for safety, stability, and efficiency.

• Rather than command only positions, calculate desired velocities and command those as well. Especially in Strategy 3 and 4, this can dramatically improve tracking of commands without relying as much on a high Kp on position.

• The gains of the effort (i.e. torque) controller generally do not have to be tuned much from their default values. The gains on the position and velocity controllers are usually where most of the tuning occurs.

• When commanding velocities, set the the Kd on position to 0, since the Kp on velocity will serve the same purpose.

• In some cases, low-passing the ouputs of the PID controllers (particularly the torque and velocity controllers) can provide more stable control, at the expense of lag in the output.

• In the case of a robot arm, the proximal actuators closer the base that bear more load will generally have higher position and velocity gains than the more distal actuators out at the wrist.

• Use commanded effort, rather than high integral gain on the position controller, to handle disturbances that can be modeled for your robot. This is often things like gravity compensation for an arm.

• Make use of the PWM plot in the Scope GUI, or the commanded PWM feedback in the APIs, to understand how the controllers are responding and combining during tuning. For example this plot can indicate if there is jitter from aggresive gains on a noisy proportional or derivative signal, or how quickly an intergral term is winding up.

## Kinematics

In each API, we provide libraries and tools that help calculate and solve problems related to a robot’s kinematics. These tasks include things like calculating forwards kinematics and Jacobians, as well as solving inverse kinematics. In addition to kinematic information that describes the physical geometry of a system, our APIs provide basic information (mass and inertias of each body) about the robot’s dynamics. This aids in calculating the torques and forces needed for tasks like gravity compensation, balancing, or quick movements.

### Body Types

The kinematic structure of the robot can be specified using built-in body types. A body can be either a static component (e.g. link) or a dynamic component (e.g. joint). Currently, our kinematics APIs only support serial chains of these bodies.

Parameterized body types are built-in to each API and correspond to components on our parts list. Please refer to the language-specific API documentation for more information on using these libraries in your application. While the types and parameters for setting up kinematics are consistent across APIs, the concrete implementation does depend on the language.

### Kinematics Setup

The first step in using the kinematics API is to configure the robot by adding bodies together in a kinematic chain. The details are API-dependent, but the overall idea is to form of chain of actuated `joints`, connected by passive `links`. The APIs have functions for quickly defining and parameterizing HEBI actuators and accessories as well as functions to fully define custom links and joints.

Additionally, you can save and load kinematic descriptions to and from files using the HEBI Robot Description Format.

The last body of the chain is considered to the the `end-effector`. All the coordinate frames for kinematics are expressed in the `BaseFrame`. The first body in the kinematic chain is by default at the origin of the `BaseFrame`. If desired, it can be set to be something different.

### Forward Kinematics

Forward kinematics refers to calculating the pose (position and orientation) of various bodies on the robot based on a given configuration (a set of joint positions).

Once the bodies of a robot are configured, the API can return the forward kinematics of the robot for a given set of joint positions as `[4 x 4]` homogeneous transforms in the base frame. In the case where the frames of multiple bodies are returned (e.g. the output frames of each body in the robot for visualization) they are returned as `m` `[4 x 4]` 3D matrix where `m` is the number of bodies in the robot.

### Jacobians

In robotics, the Jacobian, $\mathbf{J}$, refers to a matrix that relates the velocities, $\dot{\theta}$, of a robot’s joints, $\theta$, to the velocities, $\mathbf{v}$, (both linear and rotational) of various bodies of the robot, the typical case being the body that is the end effector of an arm. It also relates the torque of a robot’s joints, $\tau$, to the forces and torques, $\mathbf{f}$, on different bodies.

The Jacobian has the following relationships:

Equation Explanation Typical Use Case

$\mathbf{v} = \mathbf{J} \dot{\mathbf{\theta}}$

Body velocities equals the Jacobian times the joint velocities.

Given a robot’s joint velocities, find the resulting end-effector velocities.

$\mathbf{\dot{\theta}} = \mathbf{J}^{-1} \mathbf{v}$

Joint velocities equals the inverse of the Jacobian times the body velocities.

Given desired end-effector velocities, find the appropriate robot joint velocities.

$\mathbf{\tau} = \mathbf{J}^{T} \mathbf{f}$

Joint forces/torques equals the Jacobian-transpose times the body forces/torques.

Given a desired force/torque at the end-effector, find the appropriate robot joint torques.

$\mathbf{f} = (\mathbf{J}^{T})^{-1} \mathbf{\tau}$

Body forces/torques equals the inverse of the Jacobian-transpose times the joint forces/torques.

Given a robot’s joint torques, find the resulting end-effector forces/torques.

The Jacobian itself is a matrix of partial derivatives, defined at a given set of joint angles. The size of the Jacobian is `[6 x n]` where `n` the number of joints (degrees of freedom, of DoF) in the robot. Rows 1-2-3 of the Jacobian relate respectively to the X-Y-Z translation of a body, and rows 4-5-6 relate respectively to the X-Y-Z rotations of a body, all expressed in the base frame.

So in the equations above the vector of forces, $\mathbf{f}$, and the vector of velocities, $\mathbf{v}$, are:

$\mathbf{f} = \left[ \begin{array}{c} f_{x} \\ f_{y} \\ f_{z} \\ \tau_{x} \\ \tau_{y} \\ \tau_{z} \end{array} \right] \quad \textrm{and} \quad \mathbf{v} = \left[ \begin{array}{c} v_{x} \\ v_{y} \\ v_{z} \\ \omega_{x} \\ \omega_{y} \\ \omega_{z} \end{array} \right] .$

Once the bodies of a robot are configured, the API can calculate the Jacobian to all the different bodies for a given set of joint positions. In the case where Jacobians to multiple bodies are returned (e.g. the Jacobians to the center-of-mass of each body in the robot for compensating for the robot’s dynamics) they are returned as `m` `[6 x n]` matrices, where `m` is the number of bodies in the robot.

### Inverse Kinematics

Inverse kinematics (IK) refers to solving for the `[1 x n]` vector of joint `positions` that put the end-effector of the robot in a certain pose (position and/or orientation), where `n` is the number of joints (or DoF) in the robot. This is in general a harder problem than forward kinematics, as there can frequently be multiple or no IK solutions for a desired pose. and our approach in the HEBI APIs is to use local optimization to find an approximate solution for joint positions, given an initial 'guess' of joint positions.

The APIs allow you to provide different 'targets' for the end effector for IK solver to try to reach. You can combine multiple targets, e.g. you can solve for both the position and orientation of the end effector by specifying both `XYZ` and `SO3`. All poses are expressed in the base frame. You can also specify the `InitialPositions` for where the optimizer to starts.

 Specifying good `InitialPositions` is important for getting valid results for IK. If you are running a robot online and calculating IK at regular intverals it is often a good idea to 'warm start' the IK solver with either the commanded or feedback joint positions from the last iteration.

`XYZ`

xyz position (m)

• `[3 x 1]` vector for end-effector position (m)

• In some APIs, dimensions with `nan` get ignored, e.g., [x y `nan`] for doing IK for a planar 2-DOF arm.

`TipAxis`

z-axis orientation of end effector

• `[3 x 1]` unit vector of target direction

`SO3`

3-DoF orientation of end effector

`InitialPositions`

Initial seed for the numerical optimization. Defaults to all zeros.

## Trajectories

When controlling motion, it is important to command smooth and feasible motions to move from one pose to another.

For example, suppose you have a robot arm that has picked up an object and needs to move it from one side of a table to the other. This motion needs to take a few seconds to execute. Rather than immediately command the target joint angles that move the arm’s end-effector to the new position, a better approach is to find lots of intermediate joint angles that smoothly move to the target position, gradually speeding up and slowing down. This is what the trajectory API helps you do.

### Trajectory Generator

HEBI provides a trajectory generator API that creates smooth trajectories between various sets of joint `positions` (waypoints). These trajectories have the property that they smoothly accelerate and decelerate with "minimum jerk" and are similar to human movement. The generated trajectories are essentially a set of polynomials parameterized by `time` that can be evaluated to get intermediate `positions`, `velocities`, and `accelerations` that smoothly move between waypoints. The implementation of our trajectory generator is based on methods that have been developed to control small quadrotors.

In addition to position waypoints, there are additional constraints that can be applied so that the trajectory matches velocity and acceleration constraints at the end waypoints or any intermediate waypoints. For example, if you are controlling the swinging of a leg on a robot you can use the trajectory generator to find a smooth sweeping motion that lifts the leg up and puts it down as well as match a desired foot velocities and lift-up and touch-down.

 While the trajectory API is typically used to generate commands for HEBI Actuators, it is a general-purpose solver that can be used independently of HEBI hardware and other APIs. The trajectory generator can be used to generate workspace paths for the end-effector of an arm, or smooth motions for a mobile base.

In the table below `p` is the number of waypoints in the trajectory and `n` is number of joints (DoF) in the robot.

`positions`

`[p x n]` positions (waypoints)

Normal use is to fully specify all positions. You can manually leave positions 'free' to be solved by the generator by using `NaN`.

`times`

`[p x 1]` vector of times of when to pass through each waypoint

Values for waypoint timing must be fully specified and monotonically increasing. Time cannot go backwards or have the same value for multiple waypoints.

`velocities`

`[p x n]` velocity constraints

Optional. If not specified, beginning and end waypoints are are assumed to be `0`, and intermediate waypoints are left free. You can manually set velocities to be 'free' to be solved by the generator by using `NaN`.

`accelerations`

`[p x n]` acceleration constraints

Optional. If not specified, beginning and end waypoints are are assumed to be `0`, and intermediate waypoints are left free. You can manually set accelerations to be 'free' to be solved by the generator by using `NaN`.

 For motion to come to a full stop at an interior waypoint (any waypoint other than the first or last waypoint), the `velocities` and `accelerations` constraints both need to be set to `0`.

#### Example: Different Waypoint Timing

The following plots show examples for two trajectories that have the same waypoint `positions` but different `times`. Both trajectories have the default constraints for for `velocities` and `accelerations`, which are zero for the first and last waypoints and are left unconstrained for the intermediate waypoints. Note that timing of when to pass through a waypoint can have a significant effect on the shape of the overall trajectory.

Parameter Values - "Timing A" (Left Plot) Values - "Timing B" (Right Plot)

`positions`

`[0 1 2 1]`

`[0 1 2 1]`

`times`

`[0 1 2.5 3]`

`[0 1.5 2 3]`

#### Example: Different Waypoint Constraints

The following plots show examples for two trajectories that have the same waypoint `positions` waypoint and `times`. They differ in that the trajectory on the left has additional constraints for `velocities` and `accelerations`. Note that manually specifying additional position and velocity constraints can have a significant effect on the generated position trajectory, as well as the peak velocities and accelerations in the trajectory.

Parameter Values - "Default" (Left Plot) Values - "Constrained" (Right Plot)

`positions`

`[0 1 2 1]`

`[0 1 2 1]`

`times`

`[0 1 2.5 3]`

`[0 1 2.5 3]`

`velocities`

`[0 NaN NaN 0]` (default)

`[0 -1 -2 2]`

`accelerations`

`[0 NaN NaN 0]` (default)

`[0 0 0 0]`

### Executing a Trajectory

After a trajectory has been generated, it can be evaluated at any point in time betwen its first and last values in the `times` vector. Evaluating a trajectory at a given `time` will return a set of `positions`, `velocities`, and `accelerations` that smoothly move between waypoints.

• The `positions` and `velocities` are typically sent directly to the actuators in a robot using the Group API.

• The `accelerations` are typically passed to other tools or APIs and that use the mass, inertia, and kinematic information for a robot to calculate desired `efforts` (torques/forces) that can also be commanded.