R Field - ros
type: channel
link: http://141.11.228.10/tag/ros/
items: ros2 中用于串口通信的 serial 库
items: yahboom rosmaster x3, 其他课程 学习笔记
items: yahboom rosmaster x3, 语音控制系列课程 学习笔记
items: yahboom rosmaster x3, 深度相机系列课程 学习笔记
items: yahboom rosmaster x3, opencv系列课程 学习笔记
items: yahboom rosmaster x3, 激光雷达系列课程 学习笔记
items: yahboom rosmaster x3, 机器人底盘与控制 学习笔记
items: yahboom rosmaster x3, ROS2基础教程 学习笔记
items: yahboom rosmaster x3, 入手笔记
items: ros 串口库 rosserial

ros2 中用于串口通信的 serial 库
type: item
date: 2023-07-01T09:45:00+08:00
description: 在 ros 中，用于串口通信的是 rosserial，在 ros2 中，替代的是 micro-ROS. 创建项目 使用 stm32cube 先创建好一个工程，配置好相关的参数。 生成 micro-ros 静态库 可以先看下介绍 https://github.com/micro-ROS/micro_ros_setup 在项目文件夹下面，clone 一下 https://github.com/micro-ROS/micro_ros_stm32cubemx_utils 进入 micro_ros_stm32cubemx_util 之后，切换到 ros 版本分支，比如 foxy 根据需要，决定是否使用 dos2unix。 修改 Makefile，增加如下: ####################################### # micro-ROS addons ####################################### LDFLAGS += micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a C_INCLUDES += -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include Add micro-ROS utils C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/custom_memory_manager.c C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_allocators.c C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_time.c Set here the custom transport implementation C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c print_cflags: @echo $(CFLAGS) + 拉取生成 micro-ros 库的 docker `docker pull microros/micro_ros_static_library_builder:foxy` + 运行 `docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library microros/micro_ros_static_library_builder:foxy` + 查看生成的静态库 `micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a` # 使用 micro-ros + 参考 micro_ros_stm32cubemx_utils 下面的 sample_main ，修改项目自身的 main # 参考: + [How to setup micro-ROS on any STM32 microcontroller](https://www.youtube.com/watch?v=xbWaHARjSmk) + [【分享】microROS 和 rosserial 对比](https://fishros.org.cn/forum/topic/1960/%E5%88%86%E4%BA%AB-microros-%E5%92%8C-rosserial-%E5%AF%B9%E6%AF%94) + [stm32系列MICROROS环境配置（使用cubemx+clion+freertos）](https://fishros.org.cn/forum/topic/2423/stm32%E7%B3%BB%E5%88%97microros%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE-%E4%BD%BF%E7%94%A8cubemx-clion-freertos)

yahboom rosmaster x3, 其他课程 学习笔记
type: item
date: 2023-06-24T09:10:00+08:00

yahboom rosmaster x3, 语音控制系列课程 学习笔记
type: item
date: 2023-06-17T10:15:00+08:00

yahboom rosmaster x3, 深度相机系列课程 学习笔记
type: item
date: 2023-06-10T09:20:00+08:00

yahboom rosmaster x3, opencv系列课程 学习笔记
type: item
date: 2023-06-03T09:40:00+08:00
description: opencv 基础 基础 读取图片与展示 img = cv2.imread('yahboom.jpg', 0) cv2.IMREAD_UNCHANGED：保持原格式不变，-1； cv2.IMREAD_GRAYSCALE：以灰度模式读入图片，可以用0表示； cv2.IMREAD_COLOR：，读入一副彩色图片，可以用1表示； cv2.IMREAD_UNCHANGED：读入一幅图片，并包括其alpha通道，可以用2表示。 cv.imshow('frame', frame) 图片写入 cv2.imwrite('new_img_name', img) 摄像头读取与显示视频 capture=cv.VideoCapture(0) 参数是0，表示打开笔记本的内置摄像头，参数是视频文件路径则打开视频 ret,img = frame.read() 移动与缩放 图片缩放 cv2.resize(InputArray src,OutputArray dst, Size, fx, fy, interpolation) interpolation：插入方式，可选择 INTER_NEAREST（最近邻插值）， INTER_LINEAR（双线性插值（默认设置））， INTER_AREA（使用像素区域关系进行重采样）， INTER_CUBIC（4x4像素邻域的双三次插值）， INTER_LANCZOS4（8x8像素邻域的Lanczos插值） 图片剪切 dst = img[0:100,100:200] 图片平移 cv2.warpAffine(src, M, dsize[,dst[, flags[, borderMode[,borderValue]]]]) , M：变换矩阵, 作为仿射变换矩阵，一般反映平移或旋转的关系，为InputArray类型的2×3的变换矩阵。，只设置前三个参数的情况下，如cv2.warpAffine(img,M,(rows,cols))就可以实现基本的仿射变换效果。 dsize：输出图像的大小 flags：插值方法的组合（int 类型！） borderMode：边界像素模式（int 类型！） borderValue：（重点！）边界填充值; 默认情况下，它为0 matShift = np.float32([[1,0,10],[0,1,10]])# 2*3 dst = cv2.warpAffine(img, matShift, (width,height)) 图片镜像 for i in range(0,height): for j in range(0,width): dst[i,j] = img[i,j] dst[height*2-i-1,j] = img[i,j] 图像处理 图像灰度化处理 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 图像二值化处理 cv2.threshold（src, threshold, maxValue,thresholdType） threshold：当前阈值 maxVal：最大阈值，一般为255 thresholdType：阈值类型，一般有下面几个值， THRESH_BINARY = 0，#大于阈值的像素点的灰度值设定为maxValue(如8位灰度值最大为255)，灰度值小于阈值的像素点的灰度值设定为0。 THRESH_BINARY_INV = 1，#大于阈值的像素点的灰度值设定为0，而小于该阈值的设定为maxValue。 THRESH_TRUNC = 2，#大于阈值的像素点的灰度值设定为0，而小于该阈值的设定为maxValue。 THRESH_TOZERO = 3，#像素点的灰度值小于该阈值的不进行任何改变，而大于该阈值的部分，其灰度值全部变为0。 THRESH_TOZERO_INV = 4 #像素点的灰度值大于该阈值的不进行任何改变，像素点的灰度值小于该阈值的，其灰度值全部变为0。 返回值： retval：与参数thresh一致3 dst： 结果图像 img = cv2.imread('yahboom.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh1=cv2.threshold(gray,180,255,cv2.THRESH_BINARY_INV) 图像边缘检测 Canny边缘检测算法可以分为以下5个步骤： 使用高斯滤波器，以平滑图像，滤除噪声 计算图像中每个像素点的梯度强度和方向 应用非极大值（Non-Maximum Suppression）抑制，以消除边缘检测带来的杂散响应 应用双阈值（Double-Threshold）检测来确定真实的和潜在的边缘 通过抑制孤立的弱边缘最终完成边缘检测 op…

yahboom rosmaster x3, 激光雷达系列课程 学习笔记
type: item
date: 2023-05-27T10:25:00+08:00
description: 雷达简介与使用 功能源码在 docker 中， #A1雷达 /root/yahboomcar_ros2_ws/software/library_ws/src/sllidar_ros2/launch/sllidar_lau nch.py #A1雷达可视化 /root/yahboomcar_ros2_ws/software/library_ws/src/sllidar_ros2/launch/view_sllida r_launch.py 启动雷达 #启动A1雷达 ros2 launch sllidar_ros2 sllidar_launch.py #启动A1雷达+rviz可视化数据 ros2 launch sllidar_ros2 view_sllidar_launch.py 打印雷达数据 ros2 topic echo /scan 雷达避障趣味玩法 代码: /root/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_laser/yahboomcar_laser/las er_Avoidance_a1_X3.py 左，右，中，三个方向，每个方向如果小于设定的距离，那么就对应的方向累加。 for i in range(len(ranges)): angle = (scan_data.angle_min + scan_data.angle_increment * i) * RAD2DEG if 160 > angle > 180 - self.LaserAngle: if ranges[i] < self.ResponseDist*1.5: self.Right_warning += 1 if - 160 < angle < self.LaserAngle - 180: if ranges[i] < self.ResponseDist*1.5: self.Left_warning += 1 if abs(angle) > 160: if ranges[i] <= self.ResponseDist*1.5: self.front_warning += 1 根据不同方向上面的累加值，来决策是直行还是左右转。 if self.front_warning > 10 and self.Left_warning > 10 and self.Right_warning > 10: print ('1, there are obstacles in the left and right, turn right') twist.linear.x = self.linear twist.angular.z = -self.angular self.pub_vel.publish(twist) sleep(0.2) elif self.front_warning > 10 and self.Left_warning <= 10 and self.Right_warning > 10: print ('2, there is an obstacle in the middle right, turn left') twist.linear.x = 0.0 twist.angular.z = self.angular self.pub_vel.publish(twist) sleep(0.2) if self.Left_warning > 10 and self.Right_warning <= 10: twist.linear.x = 0.0 twist.angular.z = -self.angular self.pub_vel.publish(twist) sleep(0.5) elif self.front_warning > 10 and self.Left_warning > 10 and self.Right_warning <= 10: print ('4. There is an obstacle in the middle left, turn right') twist.linear.x = 0.0 twist.angular.z = -self.angular self.pub_vel.publish(twist) sleep(0.2) if self.Left_warning <= 10 and self.Right_warning > 10: twist.linear.x = 0.0 twist.angular.z = self.angular self.pub_vel.publish(twist) sleep(0.5) elif self.front_warning > 10 a…

yahboom rosmaster x3, 机器人底盘与控制 学习笔记
type: item
date: 2023-05-21T09:30:00+08:00
description: 机器人信息发布 代码 /root/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_bringup/yahboomcar_bringup/Mcnamu_driver_X3.py #create subcriber self.sub_cmd_vel = self.create_subscription(Twist,"cmd_vel",self.cmd_vel_callback,1) self.sub_RGBLight = self.create_subscription(Int32,"RGBLight",self.RGBLightcallback,100) self.sub_BUzzer = self.create_subscription(Bool,"Buzzer",self.Buzzercallback,100) #create publisher self.EdiPublisher = self.create_publisher(Float32,"edition",100) self.volPublisher = self.create_publisher(Float32,"voltage",100) self.staPublisher = self.create_publisher(JointState,"joint_states",100) self.velPublisher = self.create_publisher(Twist,"vel_raw",50) self.imuPublisher = self.create_publisher(Imu,"/imu/data_raw",100) self.magPublisher = self.create_publisher(MagneticField,"/imu/mag",100) #create timer self.timer = self.create_timer(0.1, self.pub_data) ros2 run yahboomcar_bringup Mcnamu_driver_X3 ros2 topic list 话题名字 话题内容 /Buzzer 蜂鸣器 /RGBLight 灯带效果控制 /cmd_vel 速度控制 /edition 版本信息 /imu/data_raw IMU传感器数据 /imu/mag IMU-磁力计数据 /vel_raw 小车速度信息 /voltage 电池电压信息 ros2 topic echo /voltage 读取电压数据 运动 ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.2}}" , 停止 ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}" 机器人控制 代码在 /root/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_ctrl/yahboomcar_ctrl/yahboo m_keyboard.py def getKey(self): tty.setraw(sys.stdin.fileno()) rlist, _, _ = select.select([sys.stdin], [], [], 0.1) if rlist: key = sys.stdin.read(1) else: key = '' termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings) return key ros2 run yahboomcar_bringup Mcnamu_driver_X3 ros2 run yahboomcar_ctrl yahboom_keyboard 键盘控制程序 节点通信图 ros2 run rqt_graph rqt_graph : 机器人状态估计 代码 /root/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_bringup/launch/yahboomcar_bringup_X3_launch.py 和 /root/yahboomcar_ros2_ws/software/library_ws/src/robot_localization/…

yahboom rosmaster x3, ROS2基础教程 学习笔记
type: item
date: 2023-05-14T08:45:00+08:00
description: 工作空间 创建工作空间 cd yahboomcar_ros2_ws mkdir -p yahboomcar_ws_ptz/src cd yahboomcar_ws_ptz 编译工作空间 colcon build source install/setup.bash echo "source ~/yahboomcar_ros2_ws/yahboomcar_ws/install/setup.bash" >> ~/.bashrc ROS2 功能包 创建功能包命令 ros2 pkg create <package_name> --build-type <build-type> --dependencies <dependencies> --node-name <node-name> cpp, ros2 pkg create pkg_helloworld_cpp --build-type ament_cmake --dependencies rclcpp --node-name helloworld py, ros2 pkg create pkg_helloworld_py --build-type ament_python --dependencies rclpy --node-name helloworld 功能包简单流程 cd ~/yahboomcar_ros2_ws/yahboomcar_ws/src ros2 pkg create pkg_helloworld_py --build-type ament_python --dependencies rclpy --node-name helloworld cd ~/yahboomcar_ros2_ws/yahboomcar_ws colcon build --packages-select pkg_helloworld_py source install/setup.bash ros2 run pkg_helloworld_py helloworld 自动生成的 helloworld.py 中，main 里面只有一条 print, 所以运行的时候，也只打印了一条字符串。 ros2 节点 把 helloworld.py 中引入 rclpy 的节点，再使用 logger 打印，然后 build, source, run，就可以看到循环打印了。 import rclpy # ROS2 Python接口库 from rclpy.node import Node # ROS2 节点类 import time """ 创建一个HelloWorld节点, 初始化时输出“hello world”日志 """ class HelloWorldNode(Node): def __init__(self, name): super().__init__(name) # ROS2节点父类初始化 while rclpy.ok(): # ROS2系统是否正常运行 self.get_logger().info("Hello World") # ROS2日志输出 time.sleep(0.5) # 休眠控制循环时间 def main(args=None): # ROS2节点主入口main函数 rclpy.init(args=args) # ROS2 Python接口初始化 node = HelloWorldNode("helloworld") # 创建ROS2节点对象并进行初始化 rclpy.spin(node) # 循环等待ROS2退出 node.destroy_node() # 销毁节点对象 rclpy.shutdown() # 关闭ROS2 Python接口 import rclpy from rclpy.node import Node 开关 ros2 接口，rclpy.init(args=args) rclpy.shutdown() 创建和销毁节点，node = HelloWorldNode("helloworld") node.destroy_node() 等待节点退出，rclpy.spin(node) 日志输出 self.get_logger().info("Hello World") 检查 rclpy 正常， while rclpy.ok() ros2 话题通信 publish #导入rclpy库 import rclpy from rclpy.node import Node #导入String字符串消息 from std_msgs.msg import String #创建一个继承于Node基类的Topic_Pub节点子类 传入一个参数name class Topic_Pub(Node): …

yahboom rosmaster x3, 入手笔记
type: item
date: 2023-05-13T09:35:00+08:00
description: 网络连接 电脑和手机，都需要连接到小车的 wifi 上面。 ROSMASTER：123456 静态 ip 小车关掉热点，连接上 wifi 路由器设置为固定 ip， 路由器重启 小车重启。 遥控测试 需要拔掉语音板，才可以进行测试。 开机大程序 临时关: 直接关闭终端即可。 临时开: python3 ~/Rosmaster-App/rosmaster/rosmaster_main.py 永久关: Startup Applications -> start_rosmaster_app, 去掉勾 永久开: Startup Applications -> start_rosmaster_app, 打勾 ssh 小车 jetson: yahboom 虚拟机 yahboom: yahboom vnc 如果是小车热点那无所谓，如果小车是连接 wifi，那么需要在小车上右上角 : settings -> sharing -> screen sharing , 然后启用对应 wifi 即可。 vnc 软件直接用就行了~ docker 常用命令 docker images, 查看镜像 docker ps -a， 查看容器运行状态 docker run -it yahboomtechnology/ros-foxy:4.0.5 /bin/bash ，启动 docker docker attach 容器id , 进入正在运行的容器 exit , 停止并退出容器 ctrl-P+Q, 不停止退出容器 docker start/restart/stop/kill docker rm 容器id , 删除指定容器 docker image inspect 镜像名称 , 查看镜像分层 硬件设备，带入 docker, 用 ll /dev 来查看，是有 myserial和rplidar docker run -it --device=/dev/myserial --device=/dev/rplidar yahboomtechnology/ros-foxy:4.0.5 /bin/bash ll /dev | grep ttyUSB* 带 gui 显示 ，必须 vnc 才行，ssh 不行。 docker run -it --env="DISPLAY" --env="QT_X11_NO_MITSHM=1" -v /tmp/.X11-unix:/tmp/.X11-unix yahboomtechnology/ros-foxy:4.0.5 /bin/bash 传文件 docker cp c54bf9efae47:/root/test.txt ~/ ， 容器 -> 宿主机 docker cp 11.txt c54bf9efae47:/root/ ， 宿主机 -> 容器 映射宿主机的可读写文件夹 docker run -it -v /home/jetson/temp:/root/temp yahboomtechnology/ros-foxy:4.0.5 /bin/bash 外设 查看 ll /dev | grep ttyUSB* ， 查看 usb 设备 ll /dev/astra* , 查看 astrapro plus 相机 编辑 根据 astra 相机的 bus ，修改 run_docker.sh 中对应的 bus 那两行。 默认的外设启动文件，需要 vnc 连接小车后。 ./run_docker.sh rviz2 进入 docker 多终端进入同一个 docker docker run -it yahboomtechnology/ros-foxy:4.0.5 /bin/bash docker ps -a docker exec -it 79493183bdb2 /bin/bash ctrl-P+Q 开启 exited 容器 见 07、Docker\5、进入机器人的docker容器 机器人开发环境 jupyter lab, 必须 --net=host docker run -it --net=host yahboomtechnology/ros-foxy:4.0.5 /bin/bash jupyter lab --allow-root 浏览器 http://192.168.0.110:8888/lab , 输入密码：yahboom, 路径: /root/yahboomcar_ros2_ws/ vscode ssh 安装插件 remote development 顶部选择 show and run command remote-ssh 选择 add new ssh ssh jetson@192.168.0.110 选择 .ssh/config connect linux, con…

ros 串口库 rosserial
type: item
date: 2020-10-12T14:15:00+08:00
description: ros 中，用到的串口库是 rosserial。 参考 STM32通过rosserial接入ROS通讯开发 ros-drivers / rosserial yoneken / rosserial_stm32 Hrilug/stm32_roslib 在STM32中实现ROS节点——Rosserial的用法 rosserial库用于stm32与ROS通信