全部版块 我的主页
论坛 新商科论坛 四区(原工商管理论坛) 商学院 创新与战略管理
41 0
2025-12-08

一、内容总览

本使用手册围绕基于 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/

更换外接摄像头(适用于原装摄像头异常情况)

查找设备编号

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. 自定义新动作组(添加个性化操作)
  1. 按下快捷键或执行命令:
    r
    —— 解除关节锁死,手动将机械臂摆放到目标姿态(例如“授粉姿势”);
  2. 执行:
    t
    —— 重新锁定关节,固定当前位置;
  3. 运行:
    y
    —— 终端输出五个关节的实际角度值,示例如下:
    P1=180, P2=90...
  4. 编辑参数配置文件:
    ~/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
    控制移动,
    /scan
    传输雷达数据);Launch 文件用于一键启动多个节点;参数文件支持灵活配置而无需改动代码;
  • 操作优先级顺序:先建立网络连接 → 启动底层驱动(底盘与机械臂)→ 加载感知模块(雷达与摄像头)→ 运行上层控制逻辑(循迹、YOLO、作业演示);
  • 常见调试策略:遇到异常首先查看终端报错信息 → 检查物理连接(串口线、电源线)→ 核对参数文件中的串口号和速度设定 → 查看识别结果图像(如 mask.jpg)或终端打印的测距数据。

遵循本手册步骤,即可完成农业机器人自主导航、环境感知与典型农务操作。如需扩展功能(如增加作物识别类别、定制机械臂动作序列),可在现有框架基础上调整参数或追加控制逻辑。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群