How to Add a New Control Algorithm

The control algorithm in Apollo consists of one or more controllers that can be easily changed or replaced with different algorithms. Each controller outputs one or more control commands to CANbus. The default control algorithm in Apollo contains a lateral controller (LatController) and a longitudinal controller (LonController). They are responsible for the vehicle control in the lateral and longitudinal directions respectively.

The new control algorithm does not have to follow the default pattern, e.g., one lateral controller + one longitudinal controller. It could be a single controller or a combination of any number of controllers.

Complete the following task sequence to add a new control algorithm:

  1. Create a controller

  2. Add the new controller configuration into the control_config file

  3. Register the new controller

The steps are elaborated below for better understanding:

Create a Controller

All controllers must inherit the base class Controller, which defines a set of interfaces. Here is an example of a controller implementation:

namespace apollo {
namespace control {

class NewController : public Controller {
 public:
  NewController();
  virtual ~NewController();
  Status Init(const ControlConf* control_conf) override;
  Status ComputeControlCommand(
      const localization::LocalizationEstimate* localization,
      const canbus::Chassis* chassis, const planning::ADCTrajectory* trajectory,
      ControlCommand* cmd) override;
  Status Reset() override;
  void Stop() override;
  std::string Name() const override;
};
}  // namespace control
}  // namespace apollo

Add a New Controller Configuration to the control_config File

To add the new controller configuration complete the following steps:

  1. Define a proto for the new controller configurations and parameters based on the algorithm requirements. An example proto definition of LatController can be found at: modules/control/proto/lat_controller_conf.proto

  2. After defining the new controller proto, e.g., new_controller_conf.proto, type the following:

    syntax = "proto2";
    
    package apollo.control;
    
    message NewControllerConf {
        double parameter1 = 1;
        int32 parameter2 = 2;
    }
    
  3. Update control_conf.proto at modules/control/proto/control_conf.proto:

    optional apollo.control.NewControllerConf new_controller_conf = 15;
    
  4. Update ControllerType in this file:

    enum ControllerType {
        LAT_CONTROLLER = 0;
        LON_CONTROLLER = 1;
        NEW_CONTROLLER = 2;
      };
    
  5. When the protobuf definition is complete, update the control configuration file accordingly at modules/control/conf/control_conf.pb.txt

Note: The above `control/conf` file is the default for Apollo.  Your project may use a different control configuration file.

Register the New Controller

To activate a new controller in the Apollo system, register the new controller in ControllerAgent. Go to:

modules/control/controller/controller_agent.cc

Type your registration information in the shell. For example:

void ControllerAgent::RegisterControllers() {
  controller_factory_.Register(
      ControlConf::NEW_CONTROLLER,
      []() -> Controller * { return new NewController(); });
}

After this code update sequence is complete, you new controller should take effect in the Apollo system.