在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
背景介绍
机器人操作系统(ROS)是机器人开发领域的核心框架,它提供了一系列工具和库来简化复杂机器人系统的构建。在嵌入式平台如RK3588上运行ROS具有重要实际意义,因为它能让我们在资源受限的设备上实现复杂的机器人功能。
本文将详细介绍如何在RK3588开发板上:
- 使用Docker容器化环境安装ROS1(Noetic)
- 创建模拟场景节点(小球绕圆柱运动)
- 实现多模态数据可视化(点云、标记、图像)
- 使用RVIZ进行实时数据展示
这种容器化ROS开发方法不仅适用于RK3588,也可用于其他嵌入式平台,为机器人开发提供了可靠的环境隔离和部署便利性。
完整操作步骤
1. 创建Docker容器环境
在嵌入式开发中使用Docker容器有三大优势:
- 环境隔离:避免污染主机系统
- 可移植性:环境可轻松迁移到其他设备
- 依赖管理:简化复杂依赖的安装过程
创建启动脚本:
cat> run_ros.sh <<-'EOF'
#!/bin/bash
image_name="ubuntu:20.04"
echo $image_name
container_name="ros_rk3588"
if [ $(docker ps -a -q -f name=^/${container_name}$) ]; then
echo "容器 '$container_name' 已经存在。"
else
echo "容器 '$container_name' 不存在。正在创建..."
docker run -id --privileged --net=host \
-v /etc/localtime:/etc/localtime:ro \
-v $PWD:/home -e DISPLAY=$DISPLAY -w /home \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e GDK_SCALE -e GDK_DPI_SCALE \
--name $container_name --hostname=$container_name $image_name /bin/bash
fi
docker start $container_name
docker exec -ti $container_name bash
EOF
2. 验证GUI显示功能
bash run_ros.sh # 进入容器
apt update
apt install x11-apps -y # 安装基础图形工具
xclock # 测试GUI显示
成功运行xclock并看到时钟界面,说明Docker的GUI转发配置正确。
3. 安装ROS Noetic
ROS Noetic是最后一个支持Python2的ROS1版本,兼容性好:
# 添加ROS软件源
apt install lsb-core -y
sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# 安装必要工具
apt install curl vim -y
# 添加ROS密钥
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
# 安装ROS完整桌面版
apt update -y
apt install ros-noetic-desktop-full -y
# 安装开发工具
apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential -y
# 安装Python依赖
apt install python3.8 pip -y
pip3 install opencv-python==4.11.0.86 -i https://mirrors.aliyun.com/pypi/simple/
# 初始化ROS依赖系统
rosdep init
rosdep update
4. 配置环境变量
确保每次启动时自动加载ROS环境:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
echo "127.0.0.1 ros_rk3588" >> /etc/hosts
5. 创建ROS节点(小球运动模拟)
cat > v2x_node_top_view.py <<-'EOF'
import rospy
import numpy as np
from sensor_msgs.msg import PointCloud2, Image as ImageRos
from visualization_msgs.msg import Marker, MarkerArray
from cv_bridge import CvBridge
import math
import cv2
from sensor_msgs.msg import Image,PointCloud2,Imu
from std_msgs.msg import Header
import sensor_msgs.point_cloud2 as pcl2
# 生成圆柱点云
def generate_cylinder(center_x, center_y, radius, height, num_points=500):
points = []
for _ in range(num_points):
# 随机角度和高度
theta = np.random.uniform(0, 2*np.pi)
h = np.random.uniform(0, height)
# 计算点坐标
x = center_x + radius * np.cos(theta)
y = center_y + radius * np.sin(theta)
z = h
# 添加到点云 (x,y,z + 强度)
points.append([x, y, z, 0.0])
return np.array(points, dtype=np.float32)
# 创建可视化Marker
def create_cylinder_marker(center_x, center_y, height, radius, id_num, frame_id="map"):
marker = Marker()
marker.header.frame_id = frame_id
marker.header.stamp = rospy.Time.now()
marker.ns = "cylinders"
marker.id = id_num
marker.type = Marker.CYLINDER
marker.action = Marker.ADD
# 位置和尺寸
marker.pose.position.x = center_x
marker.pose.position.y = center_y
marker.pose.position.z = height/2 # 中心位于半高
marker.pose.orientation.w = 1.0
marker.scale.x = radius * 2
marker.scale.y = radius * 2
marker.scale.z = height
# 颜色 (RGBA)
marker.color.r = 0.0
marker.color.g = 1.0
marker.color.b = 0.0
marker.color.a = 0.5 # 半透明
marker.lifetime = rospy.Duration()
return marker
def create_ball_marker(x, y, z, id_num, frame_id="map"):
marker = Marker()
marker.header.frame_id = frame_id
marker.header.stamp = rospy.Time.now()
marker.ns = "ball"
marker.id = id_num
marker.type = Marker.SPHERE
marker.action = Marker