I have integrated the ros pid controllers in the read and write functions of the hardware interface of my robot like this:
RRBotHWInterface::RRBotHWInterface(ros::NodeHandle &nh, urdf::Model *urdf_model)
: ros_control_boilerplate::GenericHWInterface(nh, urdf_model)
{
ROS_INFO_NAMED("rrbot_hw_interface", "RRBotHWInterface Ready.");
left_wheel_pid_controller.initPid(0.1, 0.01, 0.01, 255, -255);
right_wheel_pid_controller.initPid(0.1, 0.01, 0.01, 255, -255);
radi = 0.049;
min_ang = 0.00119361423;
prev_right_wheel_pos = 0;
prev_left_wheel_pos = 0;
max_pwm_to_max_vel_radio = 80.7501211252;
time = ros::Time::now();
duration = ros::Duration(0.001);
Setup();
}
void RRBotHWInterface::read(ros::Duration &elapsed_time)
{
const char* enc_data = Read();
std::vector<std::string> result;
boost::split(result, enc_data, boost::is_any_of(","));
if(result.size()==2) {
int curr_left_wheel_pos = atof(result[0].c_str());
int curr_right_wheel_pos = atof(result[1].c_str());
int delta_left_wheel_pos = prev_left_wheel_pos - curr_left_wheel_pos;
int delta_right_wheel_pos = prev_right_wheel_pos - curr_right_wheel_pos;
joint_position_[0] += delta_left_wheel_pos * min_ang;
joint_velocity_[0] = (delta_left_wheel_pos * min_ang)/elapsed_time.toSec();
joint_position_[1] += delta_right_wheel_pos * min_ang;
joint_velocity_[1] = (delta_right_wheel_pos * min_ang)/elapsed_time.toSec();
prev_left_wheel_pos = curr_left_wheel_pos;
prev_right_wheel_pos = curr_right_wheel_pos;
}
}
void RRBotHWInterface::write(ros::Duration &elapsed_time)
{
// Safety
enforceLimits(elapsed_time);
//int joint2_out_pow = max_pwm_to_max_vel_radio * joint_velocity_command_[0];
//int joint1_out_pow = max_pwm_to_max_vel_radio * joint_velocity_command_[1];
double pow1_error = joint_velocity_command_[0] - joint_velocity_[0];
double pow2_erro = joint_velocity_command_[1] - joint_velocity_[1];
int joint1_out_pow = pid1.computeCommand(pow1_error,elapsed_time);
int joint2_out_pow = pid1.computeCommand(pow2_error,elapsed_time);
if(joint1_out_pow>255)
joint1_out_pow = 255;
else if(joint1_out_pow<-255)
joint1_out_pow=-255;
if(joint2_out_pow>255)
joint2_out_pow=255;
else if(joint2_out_pow<-255)
joint2_out_pow=-255;
std::string pwm_datas = std::to_string(joint1_out_pow)+","+std::to_string(joint2_out_pow);
while(pwm_datas.length()<16) {
pwm_datas.push_back(',');
}
const char *res = pwm_datas.c_str();
if(pwm_datas.length()==16) {
Write(res);
usleep(10000);
}
}
void RRBotHWInterface::enforceLimits(ros::Duration &period)
{
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
//
// CHOOSE THE TYPE OF JOINT LIMITS INTERFACE YOU WANT TO USE
// YOU SHOULD ONLY NEED TO USE ONE SATURATION INTERFACE,
// DEPENDING ON YOUR CONTROL METHOD
//
// EXAMPLES:
//
// Saturation Limits ---------------------------
//
// Enforces position and velocity
pos_jnt_sat_interface_.enforceLimits(period);
//
// Enforces velocity and acceleration limits
// vel_jnt_sat_interface_.enforceLimits(period);
//
// Enforces position, velocity, and effort
// eff_jnt_sat_interface_.enforceLimits(period);
// Soft limits ---------------------------------
//
// pos_jnt_soft_limits_.enforceLimits(period);
// vel_jnt_soft_limits_.enforceLimits(period);
// eff_jnt_soft_limits_.enforceLimits(period);
//
// ----------------------------------------------------
// ----------------------------------------------------
// ----------------------------------------------------
}
But when i run this hardware interface with diff drive controller and publish the cmd_vel command in twist topic. The output power which is pwm in this case is not properly comming.
I asked this question in ros forum they said its not the way to use the pid controllers.
If no what is the correct method to use the pid controllers in the hardware interface with ros control boiler plate?
Plate-form: ros noetic, ubuntu 20.04.
Here i've used the read and write functions from the serial library i've used. which does the reading and writing tasks from arduino nano connected to the raspberry pi where i'm running this, where encoder data is being read and pwm to dc motors has been sent.
I have integrated the ros pid controllers in the read and write functions of the hardware interface of my robot like this:
But when i run this hardware interface with diff drive controller and publish the cmd_vel command in twist topic. The output power which is pwm in this case is not properly comming.
I asked this question in ros forum they said its not the way to use the pid controllers.
If no what is the correct method to use the pid controllers in the hardware interface with ros control boiler plate?
Plate-form: ros noetic, ubuntu 20.04.
Here i've used the read and write functions from the serial library i've used. which does the reading and writing tasks from arduino nano connected to the raspberry pi where i'm running this, where encoder data is being read and pwm to dc motors has been sent.