## 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

HEBI modules are Ethernet-enabled devices that serve as building blocks for a robot or automated system. These modules include actuators to provide physical motion, and devices to interface with other sensors and I/O. Modules run firmware that allow them to communicate over a standard Ethernet connection. Aspects of the firmware that are common to all modules are documented below, while aspects that are module-specific are covered in the in the Hardware section.

### 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 most situations, we recommend that you use dynamic address assignment (DHCP). This requires you to connect your computer and the modules into a network with router that supports DHCP. New modules ship configured for DHCP by default.
 If your network does not already have a router we recommend that you purchase a router. In some cases your network enforces security policies that do not allow unregistered devices on the network, or your computer may also have its network settings restricted or firewalled. Please work with your IT department to resolve these issues.

The image above shows the basic network configuration for communicating with HEBI actuator. The computer and the actuators are both connected to 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 Ethernet router should work. Some examples are listed below:

#### Getting Started

1. Plug the computer as well as your module(s) into the same router as shown above. You can daisy-chain multiple modules or extend the network using an Ethernet switch.

2. Power on the modules and look at the LED color. Blinking orange/green means that it is searching for an IP address. Once it turns into a green 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.

 We recomend setting up a static IP network only if you have a strong understanding of IP. For more information on manually configuring a network, please refer to Understanding TCP/IP addressing and subnetting basics.

IP addresses on each module can be set statically so that they don’t need to query for an address every time. This can be useful when:

• It is difficult to integrate a router or DHCP server

• The robot needs to interface with other equipment on static network

• The robot needs to initialize instantly on power-up

Static IP addresses can be set by right-clicking on a module’s entry in the Scope GUI as highlighted below.

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 and subnet mask. Settings will take effect after the module is restarted.

 When setting static IP addresses it is important to manually keep track of what addresses have been assigned. Every device on the network needs to have a unique IP address. If two or more devices (modules, host computers, or any other device) have the same address the network may not work. Additionally, it is important that the subnet mask be set to the same value across all devices. For almost all applications we recommend keeping the default subnet mask of `255.255.255.0`.

#### Connectionless Static IP Reset

 Connectionless static IP reset is only supported on firmware versions 15.0.0 and newer. To update your modules to the latest firmware, click the "Firmware Updates" tab in Scope.

It can be difficult to reconnect with a module if it is set to DHCP and you do not have a router on hand or if the module is set to an unknown static IP address. To recover access to the module in these circumstances, the module can be reset to a known default static IP address using the following procedure:

1. Power on the module. The LED should start fading green or blinking orange/green.

2. Press and hold the hardware reset button. On X-Series actuators, you will need to use a paper clip to press the button inside the connector cover (see images above).

3. Continue holding until the LED changes to a fast green flash and let go of the reset button.

4. The module will reset and have static IP address `10.11.12.13`.

#### Resetting Module back to DHCP

Modules can be set back to DHCP by right-clicking on the module in Scope and selecting "clear address" in the same menu as "set address".

If the module is not accessible in Scope (e.g. you don’t know its static IP address) you can also revert to DCHP by doing a hardware reset using the following procedure:

1. Make sure the module is powered off.

2. Press the hardware reset button. On X-Series actuators, you will need to use a paper clip to press the button inside the connector cover (see images above).

3. Power on the module. The LED should start fading red.

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

5. Power the module off, and then power it back on 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 applications 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 refresh or restart of the app/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.

Robot Network w/ DHCP + On-Board Computer + Router/Switch
Similar to the configuration above, but a wired router with switch ports is used. The WiFi access point is separate and connected to one of the free switch ports. This is the configuration of the Modular Chassis Kits.

Robot Network w/ DHCP + On-Board Computer + Router/Switch/AP
Similar to the configuration above, but the router, switch and WiFi access point are all combined into one unit. This is the configuration of Igor.

### 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.

### 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.

One or more of the actuator’s settable position, velocity, or effort limit safety controllers is activated.

Position Limits: If an actuator 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.

In the `Damped Spring` strategy, 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 motor thermal safety controller to less than what is currently being commanded from the actuator’s PID controllers.

On the X-Series and R-Series actuators, the motor thermal safety controller starts at 130 deg-C, and limits the temperature to stay below 155 deg-C.

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.

#### Abnormal Statuses

LED Pattern Meaning

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

Note: This is a hard on-off blink, as opposed to the slow gradual fade that means the module is running normally (see "Green Slow Fade" above in Normal Statuses).

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.

## 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.

#### Group Creation Rules

The APIs allow you to create a `Group` from a `Lookup` using queries about their `Family`, `Name`, and `MAC address`. For example, you can create a `Group` of all modules with the `Family` of `HEBI` with code such as:

``group = HebiLookup.newGroupFromFamily('HEBI')```

The most commonly used group create function uses families and names, and can optionally use wildcards for each of these. For example, to get all wrist modules on an arm, one might write:

``group = HebiLookup.newGroupFromNames({'HEBI'}, {'Wrist*'})``

You can even have more complex queries:

``````% Finds the "Shoulder" and all "Wrist" modules with family "HEBI".
group = HebiLookup.newGroupFromNames({'HEBI'}, {'Shoulder', 'Wrist*'})
% Finds all "Shoulder" and "Wrist" modules from "RobotA", all "Wheel"
% modules from "RobotB", and all other modules which have a family name
% starting with "HEBI".
group = HebiLookup.newGroupFromNames({'RobotA', 'RobotA', 'RobotB', 'HEBI*' }, {'Shoulder*', 'Wrist*', 'Wheel*', '*'})``````

This can look confusing, but the behavior is well defined for vectors of family and name inputs. The rules followed by the APIs are listed below; `F` is the number of elements in the family vector and `N` is the number of elements in the name vector:

1. If either one of the vectors is length one, then the one element in that vector gets repeated so the vectors are the same length.

2. If `F != N`, an error is thrown.

3. The entries are treated as `(family | name)` pairs. Each pair tries to match all modules that have been found on the network.

4. if `name` or `family` does not contain a wildcard, the matcher must return exactly one result; otherwise, it can return more than one. Otherwise, an error is thrown.

5. matches generated by wildcards are sorted alphabetically, first by family, then name, then MAC addres.

6. once all pairs have been processed, the entire list of matched modules is checked for duplicates (a module matched by two or more family/name pairs). If any are found, an error is thrown.

If no error is thrown, a group is returned with all of the matched modules.

### 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.

Feedback contains things like the position/velocity/effort of an actuator, the states of various input/output pins of an I/O board, and a wealth of other sensors and internal module state. The complete details of what is returned in module feedback is specific to the particular hardware or software application and are documented in the sections below:

### 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.

 We generally recommend using Strategy 4. More details are provided in the section on gain tuning.

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.

#### Strategy 4

This is the recommended control strategy for most applications.

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.

#### Strategy 3

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

#### 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.

#### 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.

#### Off

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

### 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.

The configurable safety controllers (such as the position limit strategy and its corresponding limit values) can be configured from:

#### Position Limits

Position limits can be set in firmware independently for the lower and upper bound of the allowed motion. To remove a limit, use +/- infinity (for the upper and lower limit respectively); in Scope this is represented by `inf` or `-inf`. Invalid configurations (e.g., a upper bound of -1 and lower bound of +1) are ignored by the modules.

When the module exceeds its position limit, the LED flashes orange.

There different strategies that can be activated when an actuator is at its position limit, detailed in the table below.

Strategy Description

Disabled

In this strategy, position limit values can be set and stored, but do not affect control.

Damped Spring

This strategy acts as a virtual spring, actively pushing the module back inside when it exceeds the set limit value. If the module boots up outside of the configured position limits, it will not exert any output force until it is manually moved back inside the range (or the limits are configured so that the current position is inside the range).

When outside the position range, commands are ignored unless their net effect is to direct the module back inside the range of valid positions.

For firmware earlier than v15.0.0, this is the default and only supported mode.

Hold Position

When the module is set to Hold Position, then the module attempts to control the output to hold the current position if the configured limit is exceeded (similar to the hold position M-stop strategy). To recover from this limit behavior, the position limit must be set to Disabled, the module moved inside the configured position limit range, and then reset to Hold Position.

Motor Off

When the configured limit is exceeded when in Motor Off, the control strategy is changed to Off, so the module does not actively control the output and commands are ignored. As with the Hold Position strategy, a semi-manual reset is required. The module should be moved back into the valid position limit range, and then the control strategy restored from Off to whatever the previous control strategy was.

### M-Stop Strategies

In addition to safety limits, actuators also support a Motion-Stop that can be triggered by pressing an external hardware button. The trigger action can be chosen by setting one of the following m-stop strategies.

 Enabling the motion stop does require additional hardware components.
Strategy Description

Disabled

In this strategy, triggering the m-stop has no effect.

Motor Off

When the m-stop is triggered when in Motor Off, the control strategy is changed to Off, so the module does not actively control the output and commands are ignored. In order to resume control, the m-stop has to be un-triggered and the control strategy has to be manually restored by the user.

Hold Position

When the module is set to Hold Position, then the module attempts to control the motor to hold the current motor position if the m-stop is triggered (similar to the hold position limit strategy). The control strategy does not change, and normal operation continues as soon as the m-stop is un-triggered.

### 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.

`(effort / unit_error)` or `(PWM / 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.

`(effort / (unit_error x sec))` or `(PWM / (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.

`(effort / (unit_error / sec))` or `(PWM / (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.

`(effort or PWM)` 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.

`(effort or PWM)` 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.

`(effort or PWM)`

`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)`

#### Choosing a Control Strategy

Strategy Notes

Strategy 4

This is the recommended control strategy for most applications.

The position controller commands an inner effort (torque) controller. This has the advantage that the gains on the position controller are more intuitive units of [Nm / rad error]. Additionally, the inner effort controller allows the actuator to be more actively compliant and respond much more like a linear spring in its position error.

If you are concerned primarily with position/velocity tracking, and less about compliance and force control, you may want to remove the effect of feedback from the actuator’s torque sensing. Do do this, you can set the Kp / Ki / Kd terms on the effort controller to 0, being sure to leave the Feed Forward term at 1. This will give you the same properties as what was provided in Strategy 3, but with more intuitive gains on position control. This will also let you cap the commanded torque to the inner loop by setting the Output Min / Max of the position controller.

In this strategy the velocity contoller also 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 allows Strategy 4 to have better velocity control with lower `Kp` gains than Strategy 2.

Strategy 3

No longer recommended. As its advantages for position/velocity control can be more easiliy achieved by adjusting the effort control loop gains in Strategy 4.

Strategy 2

Good for control if you want the velocity controller to act as much as possible as a linear damper (viscous damping). 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

Use 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.

#### 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.