C++ API

 

The HEBI C++ API is a object-oriented wrapper around our C library.  It is provided as source code to guarantee a maximum amount of portability between compilers, platforms, and operating systems.  It is written using the C++ 11 language specification.

The C++ API offers a Group interface for controlling multiple actuators in a synchronized fashion.  This interface provides the ability to send commands to the module, and to request feedback either synchronously or through callbacks from a background thread.


Setup

The API is currently supported on 64-bit (x64 architecture) Windows and Linux systems. The included examples use CMake, but you can choose other build systems if you have a preferred choice.

For detailed setup instructions please consult the API documentation.


Lookup

The API provides a lookup that can search the network for available devices automatically. Available devices can be selected by using configurable human-readable names or by their unique hardware mac addresses.

// Instantiate a default lookup querying all available interfaces
hebi::Lookup lookup;
    
// Print all modules that were found
this_thread::sleep_for(chrono::milliseconds(2000));
lookup.printTable();
    
// Select group by unique mac addresses
vector<hebi::MacAddress> macs;
MacAddress mac;
mac.setToHexString("00:1e:c0:8d:e0:5c");
macs.push_back(mac);
unique_ptr<hebi::Group> group1 = lookup.getGroupFromMacs(macs);
    
// Select group by human readable name
unique_ptr<hebi::Group> group2 = lookup.getGroupFromFamily("family");

Group Interface

The example below uses the synchronous feedback request function to implement a closed-loop controller that acts as a virtual spring for a single module that controls torque to drive the output towards the origin (stiffness = 1 Nm / rad).

long timeout_ms = 1000;
float k_spring = 1.0f; // N/m
hebi::GroupCommand cmd(group->size());
hebi::GroupFeedback fbk(group->size());
while (true)
{
    // Request feedback and wait for a response
    if (!(group->requestFeedback(&fbk, timeout_ms))
        continue; // timeout
        
    // Execute controller
    double position = fbk[0].actuator().position().get();
    cmd[0].actuator().torque(position * k_spring)
    group->sendCommand(cmd);
    
    // Limit frequency to 200 Hz
    this_thread::sleep_for(chrono::milliseconds(5);
}

Feedback Callbacks

The example below demonstrates the same virtual spring behavior implemented using asynchronous feedback from a managed background thread, and running on multiple actuators.  This demonstrates using std::function to call back to an external function, although other methods (lambda functions, std::bind) can also be used.


void feedback_callback(const hebi::GroupFeedback* const fbk)
{
    int numModules = group->size();
    hebi::GroupCommand cmd(numModules);
    float k_spring = 1.0f; // N/m;
    
    for(int i=0; i < numModules; i++)
    {
        double position = fbk[i].actuator().position().get();
        cmd[i].actuator().torque().set(position * k_spring);
    }
    group->sendCommand(cmd);
}

...

// Add event handler that gets called from a background thread
std::function<void(const hebi::GroupFeedback* const)> callback;
group->addFeedbackHandler(callback);

// Set callbackfrequency
group->setFeedbackFrequencyHz(200);

Other Features

The interface also supports advances features like setting controller gains, reconfiguring each actuator's internal controllers, and even the ability to bypass all on-board controllers to command motor PWM directly.


Roadmap

We are actively working on adding higher level capabilities to the C++ API. The following features are currently being developed.

  • Logging capability (close to release)
  • Kinematics (beta)
  • Trajectories (alpha)

We are also working on wrappers of the C library in other languages as well:

  • C# (beta)
  • Python (planned)

Most parts are already working, but we want to do more testing before a public release. If you do require these capabilities and want to be part of our pre-release testing, please contact us.