Skip to content
vpradeep07 edited this page Nov 9, 2012 · 28 revisions

Setting up a new robot

This page walks you through the steps to set up a new robot to work with the controller manager. When you make your robot support one or more of the standard interfaces, you will be able to take advantage of a large library of controllers that work on the standard interfaces.

Hardware Interface Example

Using an existing interface

Suppose we have a robot with 2 joints: A & B. Both joints are position controlled. In this case, your robot should provide the standard `JointCommandPositionInterface`, so it can re-use all controllers that are already written to work with the `JointCommandPositionInterface`. The code would look like this:

class MyRobotHW : public JointCommandPositionInterface
{
public:
  RobotHW() { }

  const std::vector<std::string> getJointNames()
  {
    std::vector<std::string> names;
    names.push_back("A");
    names.push_back("B");
    return names;
  }

  double* getPositionCommand(const std::string& name)
  {
    if (name == "A")
      return cmd[0];
    else if(name == "B")
      return cmd[1];
    else
      throw Error(name + "is not a known");
  }

  double* getPosition(const std::string& name)
  {
    if (name == "A")
      return pos[0];
    else if(name == "B")
      return pos[1];
    else
      return Error(name + " is not known");
  }

  double* getVelocity(const std::string& name)
  {
    if (name == "A")
      return vel[0];
    else if(name == "B")
      return vel[1];
    else
      return Error(name + " is not known");
  }


  double* getEffort(const std::string& name)
  {
    if (name == "A")
      return eff[0];
    else if(name == "B")
      return eff[1];
    else
      return Error(name + " is not known");
  }

private:
  double cmd[2];
  double pos[2];
  double vel[2];
  double eff[2];
}

That's it! So how is this code actually controlling your robot? The functions above are designed to give the controller manager (and the controllers inside the controller manager) access to the joint state of your robot, and to the commands of your robot. When the controller manager runs, the controllers will read from the pos, vel and eff variables in your robot, and the controller will write the desired command into the cmd variable. It's your job to make sure the pos, vel and eff variables always have the latest joint state available, and you also need to make sure that whatever is written into the cmd variable gets executed by the robot. To do this, you could for example add a read() and a write() function to your robot class. In your main(), you'd then do something like this:

main()
{
  MyRobot robot;
  ControllerManager cm;

  while (true)
  {
     robot.read();
     cm.update();
     robot.write();
     sleep();
  }
}

As the image above suggests, you're of course not limited to inheriting from only one single interface. Your robot can provide as many interfaces as you like. Your robot could for example provide both the `JointCommandPositionInterface` and the `JointCommandVelocityInterface`, and many more.

Creating a robot-specific interface

The standard interfaces are pretty awesome if you don't want to write a whole new set of controllers for your robot, and you want to take advantage of the libraries of existing controllers. But what if your robot has some features that are not supported by the standard interfaces? Does that mean you can't use the standard interfaces at all? Guess what, turns out you can do both! You can use the standard interfaces (and re-use the standard controllers) for the features of your robot that are standard. And at the same time you can expose your robot-specific features in a robot-specific interface. Take another look at the image above, and see how it shows a robot with both standard and robot-specific interfaces.

What does the code look like for such a situation?

class MyRobotHW : public JointCommandPositionInterface
{
public:
  RobotHW() { }

  // standard joint command position interface
  ...
  ...  (see code for the standard interface above)
  ...

  // Custom interfaces
  bool doSomethingCool();
  void myRobotDoesThis(int something);
};

So the custom interfaces are nothing more than adding any number of function calls to your robot class. These robot-specific functions will only be available to controllers that are specifically designed for your robot, but at the same time, your robot will still work with standard controllers using the standard interfaces of your robot.

Clone this wiki locally