[ros] ros入门记录
ROS入门
半天入门ROS,总体感觉比较好理解,python写不用编译超级爽,学完ros去学电控去了。
ros2比ros1好用,所以最终是学ros2.
ros1
安装
添加源
> 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
知识点
话题、服务。
话题有发布者和订阅者,发布者只管发布,订阅者只管开门让数据进来。发布的数据叫话题。
服务就是常用的
指令
- rosrun 后面接包名 + 节点名,运行节点
- roscore启动master
- rosnode list显示所有节点 rosnode info 节点名
- rqt_graph显示节点关系图
- rostopic list同理
- 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下问题
- 好像只能python2
- 必须在文件头加上#!/usr/bin/env python2
- 我本来加的是#!/usr/bin/env python 结果报错no module named rospkg,感觉是python版本问题,遂换成python2解决。
- python写完之后不需要编译,直接rosrun即可。
- 记得给可执行权限。
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()
ros2
由于ros1对python3的支持非常差,ros2对python3的支持非常好,所以要花一定时间学习ros2.
安装
本来准备装最新的ROS 2 Dashing Diademata,中间报错也不会解决,网上相关资料相当少,遂放弃,根据古月居的教程安装了Crystal Clemmys。
- 设置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
- 更新软件源
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'
- 安装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
- 安装自动补全工具
ros2的命令行使用argcomplete工具进行补全,所以需要安装该工具:
sudo apt install python3-argcomplete
- 设置环境变量
和ROS 1一样,为了让系统找到ROS命令,安装完成后需要将以下语句添加到.bashrc中:
source /opt/ros/crystal/setup.bash
- 安装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