Adding a New Controller¶
This section provides instructions on how to add a new controller to the platform.
parseIni.h¶
In the
config_defsnamespace for the joint(s) you are creating a controller for, add the new controller to the enum class so it can be referenced.In the
config_mapnamespace, add an entry for the joint(s) you are creating a controller for with the name that will be used in theconfig.inifile.
ControllerData.h (Controller Definition)¶
In the
controller_defsnamespace, add a namespace for your controller following the template from the existing controllers:Create idx values that will be used to access the different parameters (remember, indexing starts at 0).
Add a num_parameter value that stores the number of parameters the controller needs.
If this number is larger than the current
max_parametersincontroller_defs, updatemax_parametersaccordingly.
Controller.h¶
In
Controller.h, create a new controller that inherits from the_Controllerclass.This new controller must include:
A constructor that takes in the joint ID and an
exo_datapointer.A destructor.
A
calc_motor_cmd()function that returns the torque command in mNm.
Additional private functions or variables can be added as needed, but note that external calls will only invoke these three required functions.
ControllerData.h (Optional Additional Data)¶
(Optional) At the bottom of
ControllerData.h, you can add any extra variables for your controller that you would like to plot. These would serve as replacements or supplements to the variables defined inController.h.To assign values to these parameters in
Controller.cpp, use the following formatting:controller_data->NAMEOFVARIABLE = VALUE;
Controller.cpp¶
Define all the functions for your new controller. - When calling the constructor, make sure to use an initializer list for the base class
_Controller.
Joint.h¶
Within the header file for the joint (hip, knee, ankle) where the controller applies, add an object instance of your new controller.
Joint.cpp¶
For each joint that your controller is valid for:
Add the constructor for the new controller object in the initializer list.
In the
set_controller()function, add a new case to the switch statement:Reference the joint controller namespace in the
config_defsnamespace.Use one of the existing controllers as a template.
This case will determine which controller object the
_controllerpointer uses.Remember: End the case with a
break;statement.
Note: The switch statement references the
config_defsname, and the value passed to_controllershould reference the object created inJoint.h.
Create Parameter File¶
In the SDCard folder corresponding to the joint your controller is for, create a new parameter CSV file. It is recommended to copy one of the existing files as a starting template.
The first cell in the first line should indicate the number of header lines. Parameter reading will begin after this number of lines.
The first cell in the second line should state the number of parameters to read; this must match the value specified in
ControllerData.h.After the header, list the parameter sets you wish to use, one set per line. The parameters should be listed in the order defined by
ControllerData.h. The first set will be used as the default.If the controller applies to multiple joints, copy the file into the corresponding joint folders.
ParamsFromSD.h¶
Within the
controller_parameter_filenamesnamespace, navigate to the appropriate joint.Link the controller ID from
config_defswith the path on the SD card for the parameter file you just created.
uart_commands.h¶
(Optional) If you want to plot or save one of the variables defined in
ControllerData.h, proceed as follows inget_real_time_data(): - Find the case corresponding to the joint where your controller is used (e.g.,bilateral_hip). - Assign the variable to one of the data spots in therx_msgstructure (e.g.,rx_msg.data[0]).For controller-specific variables, format the assignment like this:
rx_msg.data[#] = exo_data->NAME_side.JOINT.controller.VARIABLENAME;
where: -
NAME_sideshould be eitherleft_sideorright_side, -JOINTis the joint you are working with, and -VARIABLENAMEis the variable to plot.To plot variables specific to a side (defined in
SideData.h), you may use:rx_msg.data[#] = exo_data->NAME_side.VARIABLENAME;
Done¶
Your new controller should now be integrated and ready to use!
Remember to change the active controller and update the parameters as necessary.