ROS与Arduino学习(八)电机控制(基于rosserial_arduino)
Tutorial Level:小案例节点通信
Tips 1 Arduino上实现ROS Node,订阅Twist msg
a.首先需要包含ros的头文件
#include
#include
#include
#include
#include
#include
#include
b. 在声明部分什么node句柄
ros::NodeHandle nh;
c.定义收到Twist msg后的处理函数
void motor_cb(const geometry_msgs::Twist& vel)
{
linear = vel.linear.x * 100; //ROS中的单位是m/s;这里换算成cm的单位,在Diego机器人中使用CM作为单位
angular = vel.angular.z;
}
ros::Subscriber<:twist> sub("/turtle1/cmd_vel", motor_cb);/这里先暂时订阅Turtle1 package的Twist消息,后面根据自己的需要可以修改
d .在loog中执行
nh.spinOnce();
到这里Arduino已经可以作为一个Node的节点接收上位机的Twist msg了
Tips 2 底盘驱动及PID控制
a. 引脚定义
底盘马达驱动采用了L298P模块
#define E_left 5 //L298P直流电机驱动板的左轮电机使能端口连接到数字接口5
#define M_left 4 //L298P直流电机驱动板的左轮电机转向端口连接到数字接口4
#define E_right 6 //连接小车右轮电机的使能端口到数字接口6
#define M_right 7 //连接小车右轮电机的转向端口到数字接口7
电机马达码盘中断,
#define Pin_left 2 //外部中断0,左轮
#define Pin_right 3 //外部中断1,右轮
b.底盘前进控制
void advance()//前进
{
digitalWrite(M_left, HIGH);
analogWrite(E_left, val_left);
digitalWrite(M_right, HIGH);
analogWrite(E_right, val_right);
}
void back()//后退
{
digitalWrite(M_left, LOW);
analogWrite(E_left, val_left);
digitalWrite(M_right, LOW);
analogWrite(E_right, val_right);
}
void Stop()//停止
{
digitalWrite(E_right, LOW);
digitalWrite(E_left, LOW);
}
c.PID控制
由于需要分别对两个马达控制所以需要分别设定两个马达的PID控制参数
//PID
double left_Setpoint, left_Input, left_Output, left_setpoint;
double left_kp = 1, left_ki = 0.005, left_kd = 0.0001;
PID left_PID(&left_Input, &left_Output, &left_Setpoint, left_kp, left_ki, left_kd, DIRECT);
double right_Setpoint, right_Input, right_Output, right_setpoint;
double right_kp = 0.8, right_ki = 0.005, right_kd = 0.0021;
PID right_PID(&right_Input, &right_Output, &right_Setpoint, right_kp, right_ki, right_kd, DIRECT);
即使相同型号的电机,其PID的调节参数都可能不一样,需要单独调节,需要反复测试调节,相关调节方法可以到百度
#include
//#include
#include
#include
#include
#include
#include
#define Pin_left 2 //外部中断0,左轮
#define Pin_right 3 //外部中断1,右轮
#define max_linear 20 //最大线速度cm/秒
#define max_turn_line