R/O/S学习笔记(自用)
一、Ubuntu使用入门1. 命令ls 列出当前文件目录mkdir 建立新文件夹cd 到某文件夹cd .. 回到上一级目录cd 回到主目录catkin_make 表示编译文件在catkin_ws目录下进行而不是srcctrl shift B 编译2. 文本编辑器gedit xxx.txt 表示在当前目录下建立xxx文本文件gedit 不存在的文件是新建存在的是编辑。3. source指令表示执行一连串指令通常把指令写在.sh文件中。4. Github相关在src文件下进行git clone 链接5. Terminator相关ctrl alt T 开新终端ctrl shift E/O/W分别表示横纵删终端alt和上下左右键搭配可以切换端口二、Node创建1. 结构工作空间--src--软件包--src--节点rosrun 功能包 节点2. 节点创建1首先创建工作空间mkdir -p name_ws/src cd name_ws/src # 进入创建的文件夹 catkin_init_workspace #将当前文件夹初始化为ROS的工作空间2在工作空间src目录下创建功能包cd catkin_ws/src/ catkin_create_pkg xxx_pkg rospy roscpp std_msgs #根据实际功能包修改3在工作包下的src创建节点cpp文件vscode直接创建编写cpp文件然后在cmake文件下面增加两行给权限的程序里面的节点名称不一定要和node节点的cpp文件名一样ctrl / 去掉注释建立cpp文件要注意去掉const参数4运行node节点roscore cd ~/catkin_ws catkin_make source devel/setup.bash #也可以把source指令加到.bashrc文件 rosrun 包名 节点名 #注意这节点名是加可执行权限里的那个不是cpp文件名三、通信机制I. 话题通信发布/订阅机制话题是节点间进行持续通信消息一直在不停发送和接收的一种方式话题中通讯的数据叫做消息message消息通常会按一定频率不断发送。void callbackFunc(const boost::shared_ptrtype msg) 说明type是消息类型msg是指向消息的常量指针 触发方式 spinOnce()处理一次事件 spin()持续调用处理事件 void DoWork(const demo02_talker_listener::Person::ConstPtr person_p){ // code } //demo02_talker_listener::Person 包名 消息名//创建两个节点 A 和 B 实现 A 节点通过⼀个 Topic 发送⼀段字符串“ I am a super man. \n” , 到 B 节点 , 由 B 节点接收信息并打印 B 节点接收到数据以后通过话题的⽅式返回字符串“ OK,I see. \n” 给节点A 节点 A 并打印收到节点 B 的信息利用ROS命令绘制ROS节点图 //talker程序 #include ros/ros.h //定义 ROS 消息类型中的字符串消息 #include std_msgs/String.h #include sstream void chatterCallback(const std_msgs::String::ConstPtr msg) { ROS_INFO(Message from node B: [%s], msg-data.c_str()); } int main(int argc, char **argv) { //初始化ROS节点 ros::init(argc, argv, talker); ros::NodeHandle n; //向ROS Master注册节点信息 ros::Publisher chatter_pub n.advertisestd_msgs::String(AtoB, 10); ros::Subscriber sub n.subscribe(BtoA, 10, chatterCallback); ros::Rate loop_rate(10); while (ros::ok()) //按照一定的频率循环发布消息 { std_msgs::String msg; std::stringstream ss; ss I am a super man.; msg.data ss.str(); chatter_pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); } return 0; } //listener #include ros/ros.h #include std_msgs/String.h ros::Publisher pub; void chatterCallback(const std_msgs::String::ConstPtr msg) {//在回调函数中处理消息 ROS_INFO(Message from node A: [%s], msg-data.c_str()); std_msgs::String pub_msg; std::stringstream ss; ss OK,I see.; pub_msg.data ss.str(); pub.publish(pub_msg); } int main(int argc, char **argv) { //初始化ROS节点 ros::init(argc, argv, listener); ros::NodeHandle n; //向ROS Master注册节点信息包括发布的话题名和话题中的消息类型 ros::Subscriber sub n.subscribe(AtoB, 10, chatterCallback); pub n.advertisestd_msgs::String(BtoA,10); //循环等待话题消息接受消息后进入回调函数 ros::spin(); return 0; }II. 服务通信请求/响应通信方式III. 参数服务器** ROS中Helloworld1.创建工作空间 $ mkdir -p ros_workspace /src $ cd ros_workspace /src $ catkin_init_workspace 2.创建功能包 $ catkin_create_pkg hello_world roscpp rospy std_msgs 3.编译工作空间 $ cd .. $ catkin_make 4.设置并检测环境变量 $ source devel/setup.bash 5. 编辑ROS包的源文件 切换到/src/hello_world/src 创建C源文件hello_world.cpp 6. 编辑CMakeLists.txt文件 add_executable({PROJECT_NAME}_node src/hello_world.cpp) target_link_libraries(PROJECT_NAME}_nod ${catkin_LIBRARIES}) 7. 编译ROS包 $ cd ~/rosworkspace $ catkin_make 8. 运行ROS节点 $ roscore $ cd ~/ros_workspace $ source devel/setup.bash $ rosrun hello_world hello_world #include ros/ros.h int main(int argc, char *argv[]) { // 执行ROS节点初始化rosnode list的是这个hello名字而不是rosrun的那个node名字 ros::init(argc, argv, hello); // 创建ROS节点句柄 ros::NodeHandle n; // 控制台输出hello world ROS_INFO(hello world!); return 0; } ... int main(int argc, char *argv[]) 此声明的目的是为了允许程序从命令行接收参数 argc 表示参数的数量argv 是一个指向参数字符串的数组 eg:rosrun my_package hello_node param1 param2 argc的值就是3参数分别是hello_node、param1、param2 ...1. 常用工具rostopic list列出当前系统中活跃着的话题rostopic echo 话题名称显示话题中消息包内容rostopic hz 话题名称统计消息发送频率* 运行node节点后显示的内容 ! 消息内容* rosinfo和printf有区别前者除了打印内容还会输出时间rqt_graph 圆形是node矩形是话题2. launch启动多个节点存储结构launch文件放在工作包内可以建一个launch文件夹存放launch文件。* roslaunch可以不启动roscore* 用rosinfo没有显示内容可以增加output“screen”文件格式pkg包名typecmake可执行权限那个nodename自己给节点在ros中取的名字,rosnode list里面的和rosinit的一样launch这相当于重新命名launchnode pkg type name /同上格式/launch四、URDF模型建立1.框架robot link ... /link link ... /link joint ... /joint /robot2.机器人本体根标签robot namemycar !-- inertial 设置的恒定值 -- !-- 设置 base_footprint -- link namebase_footprint visual geometry sphere radius0.001 / /geometry origin xyz0 0 0 rpy0 0 0/ /visual /link !-- 添加底盘 -- !-- 添加驱动轮 -- !-- 添加万向轮(支撑轮) -- /robot3.连杆link标签inertial 惯性矩阵、质量和重心等visual 可视化外观、材质、几何形状等collision 碰撞模型、几何形状、接触模型等sensor 与该link相关传感器如相机、激光等3.关节joint标签origin link相对于参考系的位置和姿态parent link的父链接child link的子链接axis link的旋转轴和旋转方向calibration link的初始角度和位置dynamics link的动力学参数如摩擦系数和阻尼limit link的限制如角度范围和力矩限制safety_controller link的安全控制器用于在关节超出限制时进行控制4.Xaco五、机器人运动控制Gazebo初步使用1.机器人运动控制话题/cmd_vel*** gazebo启动错误可能是因为缓存没清理干净# 杀死所有ROS/Gazebo相关进程 killall -9 roscore roslaunch rosrun gzserver gzclient # 清理Gazebo临时缓存 rm -rf ~/.gazebo/server-* ~/.gazebo/client-*补充gazebo正确关闭是在界面点击x再在终端ctrl c而不是直接ctrl c这样会导致关闭不干净*** cpp每次修改都需要重新编译才能运行2.gazebo集成urdfgazebo在集成 URDF 时需要做适配修改:(1)必须添加 collision 碰撞属性参数(2)必须添加 inertial 惯性矩阵参数(3)如果直接移植 Rviz 机器人的颜色设置无法显示颜色设置须做相应变更。collision:如果机器人link是标准的几何体形状和link的 visual 属性设置一致即可inertial:惯性矩阵的设置需结合link的质量与外形参数计算生成color:在 gazebo 中显示 link 颜色必须使用指定标签!-- Macro for inertia matrix -- !-- 球体 -- xacro:macro namesphere_inertial_matrix paramsm r inertial mass value${m} / inertia ixx${2*m*r*r/5} ixy0 ixz0 iyy${2*m*r*r/5} iyz0 izz${2*m*r*r/5} / /inertial /xacro:macro !-- 圆柱 -- xacro:macro namecylinder_inertial_matrix paramsm r h inertial mass value${m} / inertia ixx${m*(3*r*rh*h)/12} ixy 0 ixz 0 iyy${m*(3*r*rh*h)/12} iyz 0 izz${m*r*r/2} / /inertial /xacro:macro !-- 立方体 -- xacro:macro nameBox_inertial_matrix paramsm l w h inertial mass value${m} / inertia ixx${m*(h*h l*l)/12} ixy 0 ixz 0 iyy${m*(w*w l*l)/12} iyz 0 izz${m*(w*w h*h)/12} / /inertial /xacro:macro六、Rviz初步使用