ROS机器人Diego 1#制作(十四)机械臂的控制---arduino驱动

更多创客作品,请关注笔者网站园丁鸟,搜集全球极具创意,且有价值的创客作品
ROS机器人知识请关注,diegorobot
业余时间完成的一款在线统计过程分析工具SPC,及SPC知识分享网站qdo


今天从淘宝上订购的两个机械臂终于到货了,从这篇开始逐步讲解ROS机械臂的控制,这两个机械臂又花掉了800块,配的MG99R模拟舵机,如果配数字舵机每个机械臂要555元,价格还是有点小贵。机械臂安装好后如下图
这里写图片描述

本来有一块通过串口控制24路舵机控制的模块,但由于树莓派的串口已经被蓝牙所使用,现在蓝牙还要接蓝牙音箱,所以只好在找其他的舵机控制版,最后找到这款2路电机,和16路舵机控制模块,可以直接插在arduino上,通过ardunio的i2c接口控制舵机,同时通过arduino的D6、D7、D11、D12口控制电机,正好满足需求,而且其还留了两排arduino引脚插孔,可以自己焊接上两排插针,做扩展板用,这块板子淘宝价格是58元。

这里写图片描述

下图是装完机械臂后的Diego 1#的图片,看到是挺酷的
这里写图片描述

1.修改电机驱动代码

因为更换了电机驱动板,所以先要更改一下电机驱动的代码,其实很简单,只需要修改DualL298PMotorShield_h中接口中其中一个电机的控制对应arduino引脚,由原来的4和5改为11和12就可以了,代码如下:

#ifndef DualL298PMotorShield_h
#define DualL298PMotorShield_h

#include <Arduino.h>

class DualL298PMotorShield
{
  public:  
    // CONSTRUCTORS
    DualL298PMotorShield(); // Default pin selection.
    DualL298PMotorShield(unsigned char M1DIR, unsigned char M1PWM,
                           unsigned char M2DIR, unsigned char M2PWM); // User-defined pin selection. 
    
    // PUBLIC METHODS
    void init(); // Initialize TIMER 1, set the PWM to 20kHZ. 
    void setM1Speed(int speed); // Set speed for M1.
    void setM2Speed(int speed); // Set speed for M2.
    void setSpeeds(int m1Speed, int m2Speed); // Set speed for both M1 and M2.
    
  private:
    //static const unsigned char _M1DIR = 5;
    static const unsigned char _M1DIR = 12;
    static const unsigned char _M2DIR = 7;
    //static const unsigned char _M1PWM = 4;
    static const unsigned char _M1PWM = 11;
    static const unsigned char _M2PWM = 6;
};

#endif

2.修改码盘数据读取的代码

由于这款舵机控制模块是通过arduino 的I2C接口控制舵机,即arduino上的A4,A5。我们之前有一个电机码盘的数据是通过A4,A5读取的,所以修改到其他其他的模拟量接口,我在这里用了A2,A3。只需要修改encoder_driver.h对应接口引脚即可,同时要保证实际的连线也要做相应的调整,代码如下:

#ifdef ARDUINO_ENC_COUNTER
  //below can be changed, but should be PORTD pins; 
  //otherwise additional changes in the code are required
  #define LEFT_ENC_PIN_A PD2  //pin 2
  #define LEFT_ENC_PIN_B PD3  //pin 3
  
  //below can be changed, but should be PORTC pins
  //#define RIGHT_ENC_PIN_A PC4  //pin A4
  #define RIGHT_ENC_PIN_A PC2  //pin A2
  //#define RIGHT_ENC_PIN_B PC5   //pin A5
  #define RIGHT_ENC_PIN_B PC3   //pin A3
#endif
   
long readEncoder(int i);
void resetEncoder(int i);
void resetEncoders();

3.舵机控制
修改servos.h

//定义12 个舵机
#define N_SERVOS 12

//Servo servos [N_SERVOS];
//byte servoPins [N_SERVOS] = {3, 5};//由于本身没有使用arduino的PWM引脚控制舵机,所以这行注释
short servoslastpos [N_SERVOS];//0~180//记录舵机当前的位置

修改ROSArduinoBridge-diego.uno的void setup()的servo初始化代码。

void setup() {
  Serial.begin(BAUDRATE);

  // Initialize the motor controller if used */
#ifdef USE_BASE
#ifdef ARDUINO_ENC_COUNTER
  //set as inputs
  DDRD &= ~(1 << LEFT_ENC_PIN_A);
  DDRD &= ~(1 << LEFT_ENC_PIN_B);
  DDRC &= ~(1 << RIGHT_ENC_PIN_A);
  DDRC &= ~(1 << RIGHT_ENC_PIN_B);

  //enable pull up resistors
  PORTD |= (1 << LEFT_ENC_PIN_A);
  PORTD |= (1 << LEFT_ENC_PIN_B);
  PORTC |= (1 << RIGHT_ENC_PIN_A);
  PORTC |= (1 << RIGHT_ENC_PIN_B);

  // tell pin change mask to listen to left encoder pins
  PCMSK2 |= (1 << LEFT_ENC_PIN_A) | (1 << LEFT_ENC_PIN_B);
  // tell pin change mask to listen to right encoder pins
  PCMSK1 |= (1 << RIGHT_ENC_PIN_A) | (1 << RIGHT_ENC_PIN_B);

  // enable PCINT1 and PCINT2 interrupt in the general interrupt mask
  PCICR |= (1 << PCIE1) | (1 << PCIE2);
#endif
  initMotorController();
  resetPID();
#endif

  /* Attach servos if used */
#ifdef USE_SERVOS
  //int i;
  //for (i = 0; i < N_SERVOS; i++) {
    //servos[i].attach(servoPins[i]);
  //}
  int i;
  for (i = 0; i < N_SERVOS; i++) {
    servosPos[i]=90;
  }
  servodriver.begin();
  servodriver.setPWMFreq(50);
  #endif
}

修改头部的宏定义,启用servo

#define USE_SERVOS  // Enable use of PWM servos as defined in servos.h
//#undef USE_SERVOS     // Disable use of PWM servos

修改头部的宏定义,增加servo的引用和ServoDriver的控制变量servodriver

#ifdef USE_SERVOS
//#include <Servo.h>
#include "servos.h"
#include <Wire.h>
#include <ServoDriver.h>
#define SERVOMIN  102 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  512 // this is the 'maximum' pulse length count (out of 4096)
ServoDriver servodriver = ServoDriver();
#endif

修改runCommand舵机控制部分代码如下

#ifdef USE_SERVOS
    case SERVO_WRITE:
      //servos[arg1].write(arg2);
      servodriver.setPWM(arg1,0,short(SERVOMIN+arg2*(SERVOMAX-SERVOMIN)/180));//将舵机我这0~180转换为舵机控制脉冲长度
      servosPos[arg1]=short(arg2);
      Serial.println("OK");
      break;
    case SERVO_READ:
      //Serial.println(servos[arg1].read());
      Serial.println(servosPos[arg1]);
      break;
#endif
<think>好的,我现在需要帮助用户解决如何在ROS中修改或更换机器人底盘配置的问题。首先,我得回顾一下用户提供的引用内容,看看有没有相关的信息。引用[1]提到了移动机器人底盘的结构,引用[2]和[3]涉及使用ros_arduino_bridge来控制底盘,引用[4]是关于机器人信息发布的,而引用[5]讨论了电机PID控制。这些引用主要围绕底盘的结构、驱动配置和控制方法。用户的问题是想修改或定制底盘配置,可能需要调整硬件或软件部分。根据引用[2],ros_arduino_bridge需要修改Arduino固件和ROS的配置文件。这可能涉及到硬件接口的设置,比如电机引脚、编码器类型等。用户可能需要更改这些参数以适应新的底盘结构。另外,引用[5]提到PID参数的调整,如果更换了底盘的电机或轮子尺寸,可能需要重新调整控制参数以保证运动精度。所以,在步骤中应该包括硬件参数修改和软件控制调整。还需要考虑底盘驱动ROS节点,比如引用[4]中的信息发布,可能涉及话题和服务的配置。如果更换了底盘,可能需要修改发布的话题名称或消息类型,确保其他节点能正确接收数据。用户可能需要分步骤指导:先硬件配置,再软件参数调整,接着驱动修改,最后测试验证。此外,生成相关问题时要涵盖常见问题,比如如何调整PID、如何兼容不同底盘类型等。需要确保回答结构清晰,使用中文,并正确应用LaTeX格式。例如,提到PID参数时用$k_p$,$k_i$,$k_d$。同时,引用相关的引用内容,如引用[2]和[5]来支持步骤的说明。最后,检查是否有遗漏的部分,比如固件上传、权限设置(如引用[3]中的chmod命令),这些也是实际操作中容易遇到的问题,应该包含在步骤中。</think>在ROS中修改或更换机器人底盘配置需要从硬件接口、驱动参数、控制逻辑三方面进行调整。以下是具体步骤: --- ### 一、硬件接口配置 1. **修改Arduino固件** 若使用`ros_arduino_bridge`(引用[2][^2]),需调整Arduino端的引脚定义: ```cpp // ros_arduino_firmware/src/libraries/ROSArduinoBridge/MotorDriver.h #define LEFT_MOTOR_PIN 5 // 修改电机控制引脚 #define RIGHT_MOTOR_PIN 6 ``` 需根据实际电路板接线修改电机、编码器、传感器等引脚。 2. **更新底盘参数文件** 在ROS端修改`arduino_params.yaml`(引用[2][^2]): ```yaml # ros_arduino_python/config/arduino_params.yaml robot_base_type: differential # 底盘类型(差分/全向) wheel_diameter: 0.065 # 轮子直径(单位:米) track_width: 0.25 # 轮间距 encoder_ticks_per_rev: 1600 # 编码器每圈脉冲数 ``` --- ### 二、驱动控制逻辑调整 1. **适配底盘驱动节点** 若底盘类型变化(如四轮驱动),需修改底盘驱动节点的消息订阅和电机控制逻辑(引用[4][^4]): ```python # 示例:四轮驱动控制 def cmd_vel_callback(msg): left_speed = msg.linear.x - msg.angular.z * track_width/2 right_speed = msg.linear.x + msg.angular.z * track_width/2 # 扩展到四个电机 ``` 2. **调整PID参数** 更换电机或轮子后需重新校准PID(引用[5][^5]): $$u(t) = k_p e(t) + k_i \int_0^t e(\tau)d\tau + k_d \frac{de(t)}{dt}$$ 在代码中修改比例($k_p$)、积分($k_i$)、微分($k_d$)系数: ```python # PID控制器参数(引用[5][^5]) self.kp = 0.8 self.ki = 0.002 self.kd = 0.01 ``` --- ### 三、测试与验证 1. **启动底盘驱动节点** ```bash ros2 launch ros_arduino_bridge arduino.launch.py ``` 2. **发送测试指令** ```bash ros2 topic pub /cmd_vel geometry_msgs/Twist "{linear: {x: 0.2}, angular: {z: 0.5}}" ``` 3. **监控传感器数据** 通过`rviz`查看里程计、激光雷达等数据流(引用[3][^3])。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DiegoRobot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值