RC-car硬件平台搭建及arduino控制

引言

想做一个自动驾驶的demo,用于算法的验证和展示。目前完成了车辆平台的搭建和电机控制,后续会陆续更新其他部分:路径规划、激光slam建图与定位,语义地图的构建,控制算法等等。

硬件平台:

计算平台
  • Jetson TX2
  • arduino-uno
车载平台
  • RC-car
传感器
  • velodyne-16
  • Razor-9dof-imu
    在这里插入图片描述
    在这里插入图片描述

整个基本框架是Jetson TX2做上层感知,定位,路径规划的处理,arduino负责底层的电机控制。目标总体框架如下所示:
在这里插入图片描述

arduino电机控制

电机控制代码如下所示:

#include <Servo.h>
#include <ros.h>
#include <geometry_msgs/Twist.h>

class Car {
public:
    void initControler();

    void armControler();

    void writeToControler(int, int);

    float limitMotor(int);

    float limitServo(int);
  
private:
    const int MOTOR_PIN = 10;
    const int SERVO_PIN = 9;

    const int MOTOR_MAX = 2000;
    const int MOTOR_MIN = 1600;
    const int MOTOR_STOP = 1300;

    const int STEER_MIN = 1100;
    const int STEER_MAX = 1900;
    const int STEER_CENTER = 1500;

    const int noAction = 0;

    Servo motor;
    Servo steering;
};

Car car;
int motor_speed;
int steer;
volatile unsigned long dt;
volatile unsigned long t0;

ros::NodeHandle nh;
geometry_msgs::Twist vel_angular_back;

void controlCallback(const geometry_msgs::Twist& ecu) {
    car.writeToControler(ecu.linear.x, ecu.angular.z);
    vel_angular_back.linear.x = ecu.linear.x;
    vel_angular_back.angular.z = ecu.angular.z;
}


ros::Publisher ecu_back("ecu_back", &vel_angular_back);
ros::Subscriber<geometry_msgs::Twist> sub_control("control", controlCallback);

/**
 * ARDUINO INITIALIZATION
 */
void setup() {
    car.initControler();
    car.armControler();
    t0 = millis();
    
    nh.getHardware()->setBaud(57600);
    nh.initNode();
    
    nh.advertise(ecu_back);
    nh.subscribe(sub_control);
}

/**
 * ARDUINO MAIN lOOP
 */
void loop() {
    dt = millis() - t0;
    ecu_back.publish(&vel_angular_back);
    
    if (dt > 50) {
        t0 = millis();
        // to do
    }
    nh.spinOnce();
}

/**
 * CAR CLASS IMPLEMENTATION
 */
void Car::initControler() {
    motor.attach(MOTOR_PIN);
    steering.attach(SERVO_PIN);
}

void Car::armControler() {
    motor.writeMicroseconds(1500);
    steering.writeMicroseconds(STEER_CENTER);
    delay(3000);
}

float Car::limitMotor(int x) {
    if (x == noAction) {
        return MOTOR_STOP;
    }

    if (x > MOTOR_MAX) {
        x = MOTOR_MAX;
    } else if (x < MOTOR_MIN) {
        x = MOTOR_MIN;
    }
    return x;
}

float Car::limitServo(int x) {
    if (x == noAction) {
        return STEER_CENTER;
    }

    if (x > STEER_MAX) {
        x = STEER_MAX;
    } else if (x < STEER_MIN) {
        x = STEER_MIN;
    }
    return x;
}

void Car::writeToControler(int motor_speed, int steer) {
    int motorCMD, servoCMD;
    motorCMD = car.limitMotor(motor_speed);
    servoCMD = car.limitServo(steer);
    //motorCMD = motor_speed;
    //servoCMD = steer;
    motor.writeMicroseconds(motorCMD);
    steering.writeMicroseconds(servoCMD);
}

为了完成arduino电机控制与TX2的通讯,需要在TX2上面搭建一些环境:

安装arduino

sudo apt-get install arduino

安装rosserial-arduino

用途:用于arduino的ROS通讯桥接

二进制方式安装在ROS工作站(推荐)

sudo apt-get install ros-indigo-rosserial-arduino
sudo apt-get install ros-indigo-rosserial
rospack profile

源码方式安装在ROS工作站

cd <ws>/src
git clone https://github.com/ros-drivers/rosserial.git
cd <ws>
catkin_make

安装ros_lib到Arduino IDE开发环境

上面的安装会得到ros_lib,它需要复制到Arduino的开发环境,以启用Arduino与ROS通讯。

linux系统下,生成ros_lib到Linux下的Arduino库目录sketchbook/libraries(一般在用户的home目录下)

cd <sketchbook>/libraries
rm -rf ros_lib #如之前有,可以先删除
rosrun rosserial_arduino make_libraries.py .

然后,可以打开arduino IDE,找到file-examples-ros_lib是否存在,如果这一不没安装好的话,会找不到ros.h的头文件

运行ROS-arduino

写好arduino的代码之后,就可以试着运行看看

运行roscore

roscore

新终端运行,/dev/ttyUSB0为Arduino设备,设备可能是/dev/ttyUSB0,也可能是/dev/ttyACM0,需要自己确认

rosrun rosserial_python serial_node.py /dev/ttyUSB0

rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0

然后就可以在ROS中发布转向速度的话题消息,arduino节点接收消息后,完成电机控制。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您好!要使用Arduino控制JGB37-520编码器电机,您需要将编码器连接到Arduino,并使用适当的代码来控制它。以下是一些基本步骤: 1. 确保您有一个JGB37-520编码器电机和一个Arduino板。 2. 连接编码器的电源和地线到Arduino的5V和GND引脚。 3. 将编码器的A相和B相输出连接到Arduino的两个数字引脚。可以选择任何可用的数字引脚,但最好选择支持外部中断的引脚。 4. 在Arduino上编写代码来读取编码器的输出并控制电机。 以下是一个示例代码,可以用作起点: ```arduino // 定义编码器的引脚 const int encoderPinA = 2; // A相 const int encoderPinB = 3; // B相 // 定义电机驱动引脚 const int motorPin1 = 4; // 电机控制引脚1 const int motorPin2 = 5; // 电机控制引脚2 // 定义编码器计数值和方向 volatile long encoderCount = 0; volatile int encoderDirection = 0; void setup() { // 配置引脚模式 pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); // 配置编码器中断 attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE); } void loop() { // 在这里实现您的控制逻辑 // 例如,可以根据编码器计数值来控制电机的转动方向和速度 // 注意:在这个示例中,我只是简单地改变电机的方向,您可能需要根据实际需求进行更复杂的控制 if (encoderDirection == 1) { // 顺时针方向 digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); } else if (encoderDirection == -1) { // 逆时针方向 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); } else { // 停止 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); } } // 编码器中断处理函数 void updateEncoder() { // 读取A相和B相的状态 int encoderStateA = digitalRead(encoderPinA); int encoderStateB = digitalRead(encoderPinB); // 根据状态改变计数值和方向 if (encoderStateA == encoderStateB) { encoderDirection = -1; } else { encoderDirection = 1; } encoderCount += encoderDirection; } ``` 这只是一个简单的示例代码,您可以根据您的需求对其进行修改和调整。请确保仔细阅读JGB37-520编码器电机的规格和连接方式,并根据需要进行相应的调整。 希望这可以帮助到您!如有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值