[ros] ros入门记录
阅读原文时间:2023年07月09日阅读:1

ROS入门

半天入门ROS,总体感觉比较好理解,python写不用编译超级爽,学完ros去学电控去了。

ros2比ros1好用,所以最终是学ros2.

安装

添加源

> sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'

添加密匙

> sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

安装ros

> sudo apt update
> sudo apt install ros-melodic-desktop-full

初始化rosdep

> sudo rosdep init
> rosdep update

问题:

No module named 'rosdep2'

解决:

sudo update-alternatives --config python

手动切换python2

设置环境

> echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
> source ~/.bashrc

安装rosinstall

> sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential

知识点

话题、服务。

话题有发布者和订阅者,发布者只管发布,订阅者只管开门让数据进来。发布的数据叫话题。

服务就是常用的

指令

  1. rosrun 后面接包名 + 节点名,运行节点
  2. roscore启动master
  3. rosnode list显示所有节点 rosnode info 节点名
  4. rqt_graph显示节点关系图
  5. rostopic list同理
  6. rostopic pub 话题名 内容 加上-r 可以指定每秒循环发多少次

工作空间

创建工作空间

mkdir -p catkin_ws/src
cd catkin_ws/src
catkin_init_workspace

编译空间

cd catkin_ws
catkin_make

设置环境变量

source devel/setup.sh

检查环境变量

echo $ROS_PACKAGE_PATH

创建功能包(必须要)

cd src
catkin_create test_pkg roscpp rospy std_msgs

编译功能包

cd catkin_ws
catkin_make
source devel/setup.bash

python下问题

  1. 好像只能python2
  2. 必须在文件头加上#!/usr/bin/env python2
  3. 我本来加的是#!/usr/bin/env python 结果报错no module named rospkg,感觉是python版本问题,遂换成python2解决。
  4. python写完之后不需要编译,直接rosrun即可。
  5. 记得给可执行权限。

coding

publisher

#!/usr/bin/env python2
# license removed for brevity
import rospy
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10) # 发布话题名为chatter的topic,类型为String,队列长10
    rospy.init_node('talker', anonymous=True) # 初始化节点,节点名为talker
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()# 每隔100ms 一次

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

listener

#!/usr/bin/env python2
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)

def listener():

    rospy.init_node('listener', anonymous=True) # 节点初始化,后面表示节点匿名化,可以保证节点名的唯一性,用于接收的节点一般不需要暴露节点名吧?

    rospy.Subscriber("chatter", String, callback) # 订阅chatter话题,这里只需要指定话题,因为多个不同的节点可能发布同一话题

    rospy.spin()# 循环调callback直到结束

if __name__ == '__main__':
    listener()

由于ros1对python3的支持非常差,ros2对python3的支持非常好,所以要花一定时间学习ros2.

安装

本来准备装最新的ROS 2 Dashing Diademata,中间报错也不会解决,网上相关资料相当少,遂放弃,根据古月居的教程安装了Crystal Clemmys。

  1. 设置UTF-8编码

    sudo locale-gen en_US en_US.UTF-8

    sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8

    export LANG=en_US.UTF-8

  2. 更新软件源

    sudo apt update && sudo apt install curl gnupg2 lsb-release

    curl http://repo.ros2.org/repos.key | sudo apt-key add -

    sudo sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu lsb_release -cs main" > /etc/apt/sources.list.d/ros2-latest.list'

  3. 安装ros2(选一个速度比较快的源哦)

    export ROS_DISTRO=crystal # or bouncy or ardent

    sudo apt update

  • 桌面版安装(包含ROS, RViz, demos, tutorials)

    sudo apt install ros-$ROS_DISTRO-desktop

  • 基础版安装(包含通讯库、消息包、命令行工具,没有GUI工具)

    sudo apt install ros-$ROS_DISTRO-ros-base

  1. 安装自动补全工具

ros2的命令行使用argcomplete工具进行补全,所以需要安装该工具:

sudo apt install python3-argcomplete
  1. 设置环境变量

和ROS 1一样,为了让系统找到ROS命令,安装完成后需要将以下语句添加到.bashrc中:

source /opt/ros/crystal/setup.bash
  1. 安装ROS 1

目前ROS 2的功能还不是很全面,很多功能包需要依赖ROS 1,所以还是需要安装ROS 1的,安装方法可以参考ROS 1 wiki教程。

ROS 2和ROS 1之间通过ros-bridge通信,需要安装:

sudo apt updates
sudo apt install ros-$ROS_DISTRO-ros1-bridge ros-$ROS_DISTRO-turtlebot2-*

创建工作空间

mkdir -p ~/ros2_ws
cd ~/ros2_ws

编译运行节点

cd src
ros2 pkg create demo --denpendencies rclpy rclcpp std_msgs
mkdir scripts
touch talker.py

编写程序

# 引用python接口
import numpy as np
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class Talker(Node):

   def __init__(self):
       super().__init__('talker')
       self.i = 0

       # 创建一个Publisher,发布名为chatter的topic,消息类型为String
       self.pub = self.create_publisher(String, 'chatter')
       self.img = []
       # 设置定时器,周期调用定时器回调函数timer_callback
       timer_period = 1.0
       self.tmr = self.create_timer(timer_period, self.timer_callback)

   def timer_callback(self):
       # 创建String类型的消息
       msg = String()
       msg.data = 'Hello World: {0}'.format(self.i)
       self.i += 1
       self.get_logger().info('Publishing: "{0}"'.format(msg.data))
       self.img = np.array(self.img)
       # 发布消息
       self.pub.publish(msg)

def main(args=None):
   # ROS节点初始化
   rclpy.init(args=args)
   # 创建节点及发布器
   node = Talker()
   # 循环
   rclpy.spin(node)

   # 销毁节点,退出程序
   node.destroy_node()
   rclpy.shutdown()

if __name__ == '__main__':
   main()


python talker.py

查看node以及topic

ros2 node talker info
ros2 topic list