一、内容总览
本使用手册围绕基于 ROS(机器人操作系统)的农业机器人底盘,系统性地介绍了其在农业场景下的核心功能与操作方法。整套系统适配 Jetson 系列开发板,支持移动控制、环境感知及特定农用任务(如智能灌溉与授粉)。全手册共涵盖 13 个关键功能模块,以 ROS 的话题通信机制为核心架构,通过 Launch 文件实现多节点一键启动,并结合参数配置文件灵活调整运行逻辑,构建出“感知—决策—执行”的闭环作业流程。
主要功能模块包括:
- 基础配置:提供 SSH、VNC 和热点网络等远程连接方式,为后续所有操作奠定基础;
- 运动控制:支持键盘手动操控、车道线自动循迹以及 YOLO 目标识别联动控制,覆盖从“人工干预”到“全自动运行”的多种模式;
- 环境感知能力:集成雷达测距与摄像头图像采集功能,支持 WEB 实时预览,为自主导航和避障提供数据支撑;
- 硬件扩展应用:包含 5 自由度机械臂控制(支持预设与自定义动作),并演示了智能灌溉与智能授粉两大典型农业应用场景;
- 辅助运维工具:配备风扇启停控制(保障设备散热)和资源监视器(实时查看 CPU/GPU 使用情况)等功能。
/cmd_vel
二、核心指令与代码解析(通俗版)
以下内容按功能模块拆解关键技术点,采用“作用说明 + 操作步骤 + 原理简析”的结构进行讲解,即使无编程基础也可理解。
(一)环境准备与远程连接
关键连接信息(务必牢记)
| 用途 | 信息 |
|---|---|
| SSH 登录 | 用户名:epaicar,密码:ncut1234 |
| 网络连接 | 热点名称:Talos_AiCAR,密码:ncut1234,主机 IP 地址:192.168.20.100 |
| VNC 连接 | 密码:ncut1234(用于远程桌面访问) |
作用说明:通过电脑或手机连接机器人主控设备,实现远程操控,无需外接显示器即可完成全部设置与调试工作。
(二)底盘运动控制(核心功能)
1. 键盘手动控制(初学者必备)
操作指令(需开启两个终端窗口分别执行)
bash roslaunch talos_car_bringup car_control.launch
# 终端1:启动底盘底层驱动(ROS与硬件通信的桥梁)
roslaunch eprobot_start AIcar_joy.launch
# 终端2:启动键盘控制节点
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rosrun key_teleop key_teleop.py
roslaunch
第一步指令解析:
roslaunch 是 ROS 提供的一键启动工具,car_control.launch 文件会自动加载两个关键组件:
- ROS 与底盘控制器之间的串口通信节点(源码位于:
serial_node.cpp); - 监听
/cmd_vel话题的驱动程序——该话题作为机器人运动指令的“信号通道”,将高层指令转化为底层硬件可识别的串行数据。
AIcar_joy.launch
~/talos_ws/src/eprobot_start/script/ai_racecar.py
/cmd_vel
第二步指令解析:
启动键盘控制脚本后,用户可通过方向键(↑前进、←左转等)发送操作命令,程序会将这些输入转换为标准速度指令,并发布至 /cmd_vel 话题,最终由底盘驱动模块接收并执行相应动作。
/cmd_vel
进阶操作:直接通过指令控制运动
不依赖键盘,可使用如下命令手动发布运动指令:
bash rostopic pub /cmd_vel geometry_msgs/Twist "linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.5"
rostopic pub /cmd_vel geometry_msgs/Twist "linear:
x: 0.4 # 直行速度(正数前进,负数后退,范围0-1,越大越快)
y: 0.0 # 横向速度(农业机器人一般不用,固定0)
z: 0.0 # 垂直速度(忽略,底盘不会上下动)
angular:
x: 0.0 # 横滚角(忽略)
y: 0.0 # 俯仰角(忽略)
z: 2.0" # 转弯速度(正数左转,负数右转,范围0-3,越大转得越急)
原理说明:
rostopic pub 是 ROS 中用于向指定话题手动发送消息的命令;
geometry_msgs/Twist 是标准的速度数据格式模板;
只需修改其中 linear.x(控制前进/后退速度)和 angular.z(控制转向角速度)的数值,即可实现对机器人的直接控制。
rostopic pub
geometry_msgs/Twist
linear.x
angular.z
2. 车道线自动循迹功能
操作流程(两步执行)
bash python lane_detection.py
# 第一步:启动车道线识别(输出偏移量)
roslaunch velpub detect_line.launch
# 第二步:启动自动循迹控制(根据偏移量调整方向)
roslaunch velpub AIcar_move.launch
roslaunch talos_car_navigation follow_line.launch
detect_line.py
第一步:车道线识别逻辑
python
# lane_detection.py 核心代码片段
import cv2
# 读取摄像头图像
frame = cap.read()
# 图像处理+模型推理
offset = detect_offset(frame)
# 将偏移量写入共享文件
with open("/tmp/line_offset.txt", "w") as f:
f.write(str(offset))
# 源码路径:~/talos_ws/src/velpub/scripts/detect_line.py
cv2.imwrite("result/start.jpg",frame) # 可选:保存摄像头原图(调试用)
# 核心功能:用UNet神经网络识别图像中的车道线
# 计算小车中心与车道线中心的偏移量(比如偏移+5代表偏右,-3代表偏左)
offset = calculate_offset(frame) # 自定义函数:计算偏移量
print("偏移量:", offset) # 终端实时打印
# 保存偏移量和识别结果(给循迹程序用)
with open("result/note.txt", "w") as f:
f.write(str(offset))
cv2.imwrite("result/mask.jpg", mask) # 保存车道线识别后的图像(看识别效果)
功能说明:程序利用摄像头获取实时画面,通过图像算法或轻量级 AI 模型识别当前车辆相对于车道线的位置偏差,并将该偏移值写入临时文件中供其他模块调用。
调试建议:若发现识别不准,可取消注释日志输出语句,检查摄像头安装角度是否正对车道线区域。
cv2.imwrite("result/start.jpg",frame)
第二步:自动循迹控制逻辑(基于配置文件)
该过程依赖 follow_line.launch 启动文件及其关联的参数配置文件,无需编写额外代码,仅需调整参数即可。
AIcar_move.launch
核心参数配置示例:
<launch> <param name="kp" value="0.8" /> <param name="ki" value="0.0" /> <param name="kd" value="0.2" /> <param name="max_angular" value="1.0" /> </launch>
<param name="linear_x" value="0.3" /> <!-- 直行速度(建议0.3,太快容易冲出车道) -->
<param name="steer_coeff" value="0.5" /> <!-- 转向系数(越大,对偏移的反应越灵敏) -->
<param name="max_angular_z" value="1.5" /> <!-- 最大转弯速度(防止急转弯) -->
工作原理:控制系统周期性读取 /tmp/line_offset.txt 中的偏移值。例如,当检测到偏移为 +5(表示车身偏右),则自动发布一个左转指令(负角速度);若偏移为 -3(偏左),则发布右转指令进行纠正,从而实现持续居中行驶。
note.txt
angular.z=-1.0
angular.z=0.8
(三)环境感知系统(雷达 + 摄像头)
1. 雷达测距测试
启动指令
bash python lidar_test.py
# 启动雷达驱动(激光雷达LD06)
roslaunch ldlidar_stl_ros ld06.launch
# 打开RViz可视化雷达点云(看周围障碍物)
rviz
# 运行Python脚本,打印两侧距离
python get_scan_data.py # 路径:~/talos_ws/src/agrc_base_arm/script
代码逻辑解析(lidar_test.py 主要内容)
python
def lidar_callback(data):
# 获取左侧(90°)和右侧(270°)的距离
left_dist = data.ranges[90]
right_dist = data.ranges[270]
print(f"Left: {left_dist:.2f}m, Right: {right_dist:.2f}m")
# 订阅 /scan 话题
rospy.Subscriber("/scan", LaserScan, lidar_callback)
get_scan_data.py
import rospy
from sensor_msgs.msg import LaserScan
def scan_callback(data):
# data.ranges是雷达所有方向的距离数据(列表,长度360,对应0-360度)
left_distance = data.ranges[90] # 90度方向(小车左侧)的距离
right_distance = data.ranges[270] # 270度方向(小车右侧)的距离
print("左侧距离:{:.2f}m,右侧距离:{:.2f}m".format(left_distance, right_distance))
if __name__ == "__main__":
rospy.init_node("scan_data_node") # 初始化ROS节点
rospy.Subscriber("/scan", LaserScan, scan_callback) # 订阅雷达话题"/scan"
rospy.spin() # 持续运行,等待雷达数据
功能说明:雷达持续扫描周围环境,通过 /scan 话题广播各方向距离数据。本脚本订阅该话题,提取正左方与正右方的测距结果,输出至终端,可用于避障判断或精确定位停靠。
/scan
2. 摄像头图像 WEB 预览
启动步骤(需两步)
bash roslaunch usb_cam usb_cam.launch rosrun web_video_server web_video_server
# 第一步:启动摄像头驱动
roslaunch usb_cam usb_cam-test.launch
# 第二步:启动WEB服务器
rosrun web_video_server web_video_server
访问方式:
- 在机器人主机浏览器中打开:http://localhost:8080
- 手机或电脑连接同一热点后访问:http://192.168.20.100:8080
http://localhost:8080/
http://192.168.20.100:8080/
更换外接摄像头(适用于原装摄像头异常情况)
查找设备编号:
bash ls /dev/video*
ll /dev/video* # 插入USB摄像头前后各执行一次,新增的就是(比如/dev/video1)
修改配置文件路径:
/opt/ros/kinetic/share/usb_cam/launch/usb_cam.launch
~/talos_ws/src/usb_cam/launch/usb_cam-test.launch
修改内容:找到以下行,将默认的 video0 更改为实际设备号(如 video2):
<param name="video_device" value="/dev/video0" />
video0
video1
修改后保存并重启摄像头节点即可生效。
<param name="device" value="/dev/video1" /> <!-- 摄像头设备号 -->
(四)YOLO 目标检测功能(识别作物与障碍物)
启动指令:
bash roslaunch yolo_ros yolo_detect.launch
# 进入YOLO部署目录
cd /opt/nvidia/deepstream/deepstream-6.0/sources/DeepStream-Yolo
# 启动YOLO识别(基于DeepStream加速,适合Jetson硬件)
deepstream-app -c deepstream_app_config.txt
关键配置项修改:
1. 开启图像显示窗口:
编辑配置文件中的 show_image 参数:
config.ini [display] show_image = True
deepstream_app_config.txt
[sink0]
enable=1 # 1=显示图像,0=不显示
type=2 # 2=窗口显示
[osd]
enable=1 # 1=显示识别框和标签,0=不显示
2. 切换摄像头输入源:
若使用非默认摄像头,需修改以下部分:
config.ini [camera] device_id = 2
[source0]
camera-v4l2-dev-node=1 # 改成你的摄像头设备号(比如1对应/dev/video1)
3. 检测结果存储机制:
系统会自动将识别到的目标类别(如“花”、“草”、“障碍物”)记录到指定文本文件中,便于后期分析或触发联动动作。
检测结果保存路径: /home/epaicar/yolo_results/detections.log
yolosign.txt
/opt/nvidia/deepstream/deepstream-6.0/sources/DeepStream-Yolo/nvdsinfer_custom_impl_Yolo/yolosign.txt联动控制(基于识别结果驱动小车行为)
运行相关指令以实现控制逻辑。
# 启动联动控制节点
roslaunch velpub get_yolo_rst.launch
核心控制机制:
通过整合 YOLO 目标识别输出与车道线循迹模块,构建智能响应系统。当检测到障碍物时自动停车,识别到指定目标则靠近执行任务。
velpub.py
代码实现如下:
python
运行
# 订阅车道线循迹的速度指令(/cmd_vel_1)
rospy.Subscriber("/cmd_vel_1", Twist, cmd_vel_callback)
# 读取YOLO识别结果(yolosign.txt)
with open("yolosign.txt", "r") as f:
target = f.read().strip() # 比如读到"flower"(花)或"obstacle"(障碍物)
# 根据目标调整运动指令
if target == "obstacle":
# 遇到障碍物,停止前进
cmd_vel.linear.x = 0.0
cmd_vel.angular.z = 0.0
elif target == "flower":
# 识别到花,减速并转向靠近
cmd_vel.linear.x = 0.2
cmd_vel.angular.z = -0.8 # 右转靠近
# 发布最终的运动指令(/cmd_vel)
pub.publish(cmd_vel)
机械臂控制(农业作业的核心执行装置)
必要准备事项(必须完成!)
- 开机前对位:确保机械臂大臂的“对准位”与云台“对准位”贴合,防止舵机复位时卡死;
- 检查串口连接:接入机械臂 USB 后,执行以下命令确认设备识别情况;
ll /dev/ttyUSB*
默认串口号通常为:
/dev/ttyUSB2
- 设置串口权限:避免通信失败,需修改设备访问权限。
bash
运行
sudo chmod 777 /dev/ttyUSB2 # 给串口读写权限
主要控制方式(三种,由简至繁)
1. 发布预设动作话题(最常用方法)
bash
运行
# 启动机械臂驱动(自动回到初始位置)
roslaunch agrc_base_arm agrc_base_arm.launch
动作编号对照表(仅需更改 data 字段数值):
| 功能 | data 值 |
|---|---|
| 初始位姿(待机状态) | 1 |
| 动作组 1(如“伸展手臂”) | 2 |
| 动作组 2(如“抓取动作”) | 3 |
| 获取各关节角度和扭矩信息 | 20 |
| 关闭关节锁死(允许手动调节) | 99 |
| 打开关节锁死(固定当前姿态) | 100 |
# 发布指令:让机械臂执行“初始位姿”(data=1)
rostopic pub /arm_cmd std_msgs/Int32 "data: 1"
data
2. 键盘手动操控模式
| 按键 | 功能说明 |
|---|---|
| y | 打印当前各轴角度及扭矩数据 |
| r | 解除关节锁定,可手动调整位置 |
| t | 启用关节锁定,保持当前位置不变 |
3. 自定义新动作组(添加个性化操作)
- 按下快捷键或执行命令:
—— 解除关节锁死,手动将机械臂摆放到目标姿态(例如“授粉姿势”);r - 执行:
—— 重新锁定关节,固定当前位置;t - 运行:
—— 终端输出五个关节的实际角度值,示例如下:yP1=180, P2=90... - 编辑参数配置文件:
~/talos_ws/src/agrc_base_arm/config/base_arm.yaml
yaml
action_groups:
17: # 新动作组编号(16之后的数字)
- P1: 180 # 关节1位置(刚才打印的数值)
P2: 90 # 关节2位置
P3: 60 # 关节3位置
P4: 120 # 关节4位置
P5: 180 # 关节5位置(夹爪)
speed: 200 # 运动速度
保存修改后,重启机械臂驱动节点,并发布对应动作指令即可调用新增动作。
data=17
智能灌溉演示(农业场景实战应用)
整体流程:硬件安装 + 软件启动
1. 硬件连接关键点
- 水泵接线:进水口连接带过滤头的软管(放入水瓶),出水口连接喷嘴并固定于机械臂夹爪上;
- 电源管理:使用独立 12V 锂电池为水泵供电,防止短路影响主控;水泵控制器 USB 接入底盘 USB-HUB;
- 识别水泵串口:执行命令查看设备列表,
水泵控制器一般对应最后插入的设备,通常是:ll /dev/ttyUSB*/dev/ttyUSB3
2. 核心启动指令(按顺序开启四个终端)
bash
运行
# 终端1:启动底盘驱动
roslaunch eprobot_start AIcar_joy.launch
# 终端2:启动机械臂驱动
roslaunch agrc_base_arm agrc_base_arm.launch
# 终端3:启动雷达(精准停靠用)
roslaunch ldlidar_stl_ros ld06.launch
# 终端4:启动灌溉Demo
roslaunch agrc_base_arm compitation_irrigate_demo.launch
3. 参数配置说明(无需修改代码)
通过调整配置文件即可优化运行效果:
yaml
linear_x: 0.3 # 小车直行速度(慢一点,精准停靠)
anglular_z: 1.0 # 转向速度
pump_serial: /dev/ttyUSB3 # 水泵串口(必须和实际一致)
pump_on_time: 2.0 # 单次灌溉时间(2秒,根据需要调整)
pump_off_time: 1.0 # 灌溉后关闭延时(1秒)
# 行进时间配置:[前进时间(秒),停留时间(秒)]
go_along_time:
- [2.5, 5.0] # 方案1:前进2.5秒,停留5秒(给灌溉留时间)
- [3.0, 4.5] # 方案2:前进3秒,停留4.5秒
# A区任务:10次行进+停留,每次用go_along_time中的第n个方案
task_A_go_along: [0,0,1,1,0,0,1,1,0,0] # 0=方案1,1=方案2
compitation_irrigate_demo.yaml
4. 主要程序逻辑结构
软件实现流程如下:
python
运行
# 读取参数文件
config = rospy.get_param("/compitation_irrigate_demo")
linear_x = config["linear_x"]
pump_on_time = config["pump_on_time"]
# 雷达数据回调(精准停靠)
def scan_callback(data):
left_dist = data.ranges[90]
right_dist = data.ranges[270]
print("两侧距离:", left_dist, right_dist)
# 若检测到花盆(距离小于0.5米),停止前进
if left_dist < 0.5 and right_dist < 0.5:
stop_car() # 停止小车
# 灌溉动作
def irrigate():
# 控制机械臂转到灌溉姿势(发布动作组指令)
rospy.Publisher("/arm_cmd", Int32, queue_size=10).publish(5) # 动作组5=灌溉姿势
# 打开水泵
pump_serial.write(b"ON") # 向水泵控制器发“开”指令
rospy.sleep(pump_on_time) # 保持开启pump_on_time秒
# 关闭水泵
pump_serial.write(b"OFF")
rospy.sleep(config["pump_off_time"])
# 主流程
def main():
for i in range(len(task_A_go_along)):
# 按方案前进
go_time, wait_time = go_along_time[task_A_go_along[i]]
move_car(linear_x, 0.0, go_time) # 直行go_time秒
rospy.sleep(wait_time) # 停留
irrigate() # 执行灌溉
# A区完成后,去B区...
compitation_irrigate_demo.py
功能描述:小车按照预设路径在 A 区与 B 区之间移动,利用雷达探测花盆位置,到达后停止,机械臂调整姿态,启动水泵进行灌溉,完成后继续行进。
智能授粉演示(类比灌溉,简化版本)
主要区别点
- 硬件方面:不使用水泵,改用水笔固定于机械臂夹爪,模拟授粉动作;
- 软件方面:采用不同的动作组(“授粉动作”而非“灌溉动作”),且在参数文件中可缩短停留时间(因授粉速度快于灌溉)。
关键切换指令(更换运行 Demo)
bash
运行
# 终端4:启动授粉Demo(其他3步和灌溉一样)
roslaunch agrc_base_arm compitation_pollination_demo.launch
辅助工具(保障系统稳定运行)
1. 风扇启停控制(Jetson 散热必需)
Jetson 开发板在运行 AI 模型期间会产生高温,建议手动开启散热风扇:
bash
运行
# 1. 创建并编辑启动文件
sudo touch /etc/rc.local
sudo gedit /etc/rc.local
# 2. 在文件中输入以下内容(复制粘贴即可)
#!/bin/bash # 必须有,告诉系统这是bash脚本
sleep 10 # 开机10秒后执行(等系统启动完成)
sudo /usr/bin/jetson_clocks # 开启Jetson性能模式
sudo sh -c 'echo 200 > /sys/devices/pwm-fan/target_pwm' # 风扇转速(200是中等转速,范围0-255)
# 3. 给文件加执行权限
sudo chmod 755 /etc/rc.local
作用:实现开机自动启动风扇,有效预防因温度过高导致系统崩溃或机器人死机。
2. 系统资源监视器(实时监控硬件状态)
bash
运行
jtop # 直接在终端输入
功能说明:动态显示 CPU、GPU 使用率、内存占用、风扇转速及温度等关键指标。
- 若 GPU 占用达 100%,表示 YOLO 或车道线识别模型正在正常运行;
- 若温度超过 85℃,建议提高风扇转速(将原值 200 修改为 255)以增强散热。
三、核心总结
- ROS 核心架构:所有模块间通过“话题”进行通信(例如:
控制移动,/cmd_vel
传输雷达数据);Launch 文件用于一键启动多个节点;参数文件支持灵活配置而无需改动代码;/scan - 操作优先级顺序:先建立网络连接 → 启动底层驱动(底盘与机械臂)→ 加载感知模块(雷达与摄像头)→ 运行上层控制逻辑(循迹、YOLO、作业演示);
- 常见调试策略:遇到异常首先查看终端报错信息 → 检查物理连接(串口线、电源线)→ 核对参数文件中的串口号和速度设定 → 查看识别结果图像(如 mask.jpg)或终端打印的测距数据。
遵循本手册步骤,即可完成农业机器人自主导航、环境感知与典型农务操作。如需扩展功能(如增加作物识别类别、定制机械臂动作序列),可在现有框架基础上调整参数或追加控制逻辑。


雷达卡


京公网安备 11010802022788号







