B站链接:T-Robot v0.1版本发布!开源全向移动机器人(Based on Micro-ROS)
-
T-Robot是一个DIY的移动机器人
-
全面拥抱ROS2生态,可实现2D激光雷达地图重建和自主导航
-
纯兴趣向,可作为ROS2入门参考使用
-
底层采用micro-ros,彻底拥抱ROS2生态
-
上层应用ROS2进行各个功能模块的快速开发
-
本项目借鉴和学习了以下仓库:linorobot2 fishbot turtlebot3
-
注意:仅在ros2-foxy下进行了测试
- images:一些照片
- firmware:底层固件
- ros2_packages:ros功能包
- 3D-models:三维模型
均为淘宝采购,为避免广告嫌疑,不放链接~
- 机器人底盘布局
-
主控:esp32 (ESP-WROOM-32)+旭日x3派(2GB)
-
激光雷达:LD14
-
IMU:MPU9250
-
电机: WGA12-N20直流减速电机 (12V, 1:50减速比)
-
电机驱动芯片:4颗RZ7889
-
编码器:AB双相增量式磁性霍尔编码器
-
电源:12V锂电池;
- 12V驱动电机;外置12V转5V模块提供DC-5V输出(最大电流4A);
-
轮子:4麦轮,直径48mm
-
结构件:切割亚克力板、3D打印
-
此固件基于Arduino框架,适用于esp32系列;不推荐使用ArduinoIDE进行编译(可能报错);
-
推荐使用VScode+platformio,固件相关依赖可通过
platformio.ini
自动安装; -
基于micro_ros_arduino#v2.0.5foxy,可自行更改为其他版本,如
galactic
,humble
等(可能需要极少的修改); -
由于
micro_ros_arduino
并不是原生支持platformio
,因此在platformio.ini
中需要手动指定相应硬件平台的libmicroros.a
,使用如下命令(以esp32为例):build_flags = -L $PROJECT_DIR/lib/micro_ros_arduino/src/esp32/ -l libmicroros
对官方micro_ros_arduino库进行了rebuild,因此不可以直接使用官方的库
-
若要使用官方micro_ros_arduino,需要更改odomertry message的Qos为default:
- 改为default会导致发布频率降低;
//!!! 更改rclc_publisher_init_best_effort为rclc_publisher_init_default !!! RCCHECK(rclc_publisher_init_best_effort( &odom_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(nav_msgs, msg, Odometry), "odom"));
-
使用wifi与上位机进行通讯;
-
若使用串口,确保串口波特率在480600bps以上,并修改src/main.cpp:
set_microros_transports(); //set_microros_wifi_transports("WIFI名称", "密码", "上位机IP", 8888);
包含大部分宏定义,引脚定义等。
c++封装的适用于esp32的编码器库,原作者仓库地址:ESP32encoder
-
本项目对其进行了必要修改,增加了
getRPM()
函数,以直接获取转速信息。float ESP32Encoder::getRPM(int counts_per_rev) //counts_per_rev:每转一圈的编码器计数 { counts_per_rev_ = counts_per_rev; int64_t encoder_ticks = getCount(); // this function calculates the motor's RPM based on encoder ticks and delta time unsigned long current_time = micros(); unsigned long dt = current_time - prev_update_time_; // convert the time from milliseconds to minutes double dtm = (double)dt / 60000000; double delta_ticks = encoder_ticks - prev_encoder_ticks_; // calculate wheel's speed (RPM) prev_update_time_ = current_time; prev_encoder_ticks_ = encoder_ticks; return ((delta_ticks / counts_per_rev_) / dtm); }
-
可配置实现不同的编码器计数方式:
//file: ESP32encoder.h
void attachSingleEdge(int aPintNumber, int bPinNumber); //1倍
void attachHalfQuad(int aPintNumber, int bPinNumber); //2倍
void attachFullQuad(int aPintNumber, int bPinNumber); //4倍
-
imu_interface.h
-
定义了IMU的
ros2 imu message
格式,可直接发送给ROS/ROS2使用; -
IMUInterface()
构造函数中初始化了imu_msg.header
相关信息,不同版本写法略有不同; -
抽象了4个虚函数,方便适配不同类型的IMU;
//file: imu_interface.h virtual geometry_msgs__msg__Vector3 readAccelerometer() = 0; virtual geometry_msgs__msg__Vector3 readGyroscope() = 0; virtual bool startSensor() = 0; virtual void calibrateGyro()=0;
-
-
default_imu.h
- 依赖MPU9250库,该库可通过platformio.ini文件进行自动安装,也可以手动下载添加;
- 对
imu_interface.h
中的4个虚函数进行了实现;
c++封装的适用于求解小车底盘正逆运动学的库。适用于两轮差分、阿克曼、麦轮等。该库原地址:kinematics
小车轮距、轮径、转速等信息在lib/config
中定义;
- 核心函数1:由线速度和角速度推算小车车轮转速
rpm getRPM(float linear_x, float linear_y, float angular_z);
- 核心函数2:由小车车轮转速推算线速度和角速度
velocities getVelocities(int rpm1, int rpm2, int rpm3, int rpm4);
motor_interface.h
抽象了电机的各个功能,如正转、反转、停机等;
motor.h
继承了motor_interface
并对其各个功能进行了实现,并添加了pwm_offset
;
pwm_offset
是为了解决一些电机在低占空比pwm驱动下,电机不转动的问题;
定义了里程计nav_msgs/msg/odometry
,用于发布odometry message
;
-
核心函数1:获取当前的
odometry message
数据nav_msgs__msg__Odometry Odometry::getData() { return odom_msg_; }
-
核心函数2:传入速度信息,更新
odometry message
数据
void update(float vel_dt, float linear_vel_x, float linear_vel_y, float angular_vel_z);
顾名思义,电机的PID控制,不多解释了,看代码~
基于官方的micro_ros_arduino#v2.0.5foxy,对其进行了必要修改,并进行了rebuild:
- 修改
UCLIENT_CUSTOM_TRANSPORT_MTU=1024
,使得采用best_effort的传输策略时,可以传输大于512Bytes的数据(主要是odometry message); - 修改
RMW_UXRCE_MAX_HISTORY=2
,减少RAM使用,避免内存溢出; - 具体rebuild步骤可参考:micro-ROS/micro_ros_arduino#1221 (comment)
- 初始化编码器、pid控制、电机等
- 创建2个publisher: odom和imu
- 创建1个subscriber: cmd_vel
- 创建3个软件定时器:2个用于publisher发布;1个用于控制机器人移动;
- 激光雷达的功能包,一般由雷达厂家提供
- 放置robot开机启动的程序(目前只有一个default.launch.py)
- 依次启动激光雷达、robot_description、micro_agent等等
- 主要放置机器人描述文件,即urdf
- 加载stl文件报错时,可参考fix malformed stl
- 利用cartoprapher进行建图,具体信息自行学习cartographer。
- IMU坐标系未与ROS默认的坐标系对齐,需要重新对齐,后续有进度再更新。
- 因为IMU坐标系问题,采用EKF融合IMU和Odometry会出错,故直接使用编码器直出Odom。
- Odom的更新频率目前维持在40Hz,再高无法达到,似乎串口波特率到极限了;可尝试wifi通讯。
- 未添加camera驱动,因为后续有使用camera进行再次开发的想法,等待后续更新。