In this section, we can see the explanation of each section of the code:
/// Controller initialization in non-real-time
bool MyControllerClass::init(pr2_mechanism_model::RobotState *robot,
ros::NodeHandle &n)
{
std::string joint_name;
if (!n.getParam("joint_name", joint_name))
{
The preceding is the init() function definition of the controller. This will be called when a controller is loaded by the controller manager. Inside the init() function, we are creating an instance of RobotState and NodeHandle , also retrieving a joint name for attaching our controller. This joint name is defined inside the controller configuration file. We can see the controller configuration file in the next section.
joint_state_ = robot->getJointState(joint_name);
This is will create a joint state object for a particular joint. Here robot is an instance of the RobotState class and joint_name is the desired joint in which we are attaching the controller:
/// Controller startup in realtime
void MyControllerClass::starting()
{
init_pos_ = joint_state_->position_;
}
After loading the controller, the next step is to start the controller. The preceding function will execute when we start a controller. In this function, it will retrieve the current state of the joint into the init_pos_ variable:
/// Controller update loop in real-time
void MyControllerClass::update()
{
//Setting a desired position
double desired_pos = init_pos_ + 15 * sin(ros::Time::now().toSec());
//Getting current joint position
double current_pos = joint_state_->position_;
//Commanding the effort to joint to move into the desired goal
joint_state_->commanded_effort_ = -10 * (current_pos - desired_pos);
}
This is the update function of the controller, which will continuously move the joint in a sinusoidal fashion.