ros1命令

roscore   打开主节点


rosnode list  显示所有激活的节点名

rostopic list   显示所有激活的主题名

rosmsg list     显示所有消息列表


rosnode info  节点名


rosrun 包名  节点名


source devel/setup.sh 

source /opt/ros/noetic/setup.sh 


rosrun haitao fabu.py

这里haitao是包名,fabu.py是节点文件的名称


rosversion -d      查看ros的版本


 rospy.Timer(rospy.Duration(5),  指定方法)    定时5秒触发指定方法


rqt_graph   显示节点的订阅关系


catkin_make   进入工作空间目录,执行这条指令,进行编译,一般对c++节点修改添加后 都要重新编译

rosrun 功能包名  节点名

在 工作空间/src下创建一个包 ,包名后面的就是依赖 

cd  ~/工作空间名/src
catkin_create_pkg  包名  std_msgs rospy roscpp geometry_msgs turtlesim

创建的包内容如下:


 创建一个节点,并在节点里发布一个话题

可以在功能包下面创建一个文件夹scripts,专门用于存放python节点

可以在功能包/src下创建一个cpp节点

/*创建一个小海龟的速度发布者*/
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
int main(int argc, char **argv)
{
    ros::init(argc, argv, "turtle_velocity_publisher");//ROS节点初始化
    ros::NodeHandle n;//这里是创建句柄
    //创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>
    ("/turtle1/cmd_vel", 10);
    ros::Rate loop_rate(10);//设置循环的频率
    while (ros::ok())
    {
        //初始化需要发布的消息,类型需与Publisher一致
        geometry_msgs::Twist turtle_vel_msg;
        turtle_vel_msg.linear.x = 0.8;
        turtle_vel_msg.angular.z = 0.6;
        turtle_vel_pub.publish(turtle_vel_msg);// 发布速度消息
        //打印发布的速度内容
        ROS_INFO("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]",
        turtle_vel_msg.linear.x, turtle_vel_msg.angular.z);
        loop_rate.sleep();//按照循环频率延时
    }
    return 0;
}

 创建上面节点后,然后在功能包下的CMakelist.txt中添加如下

add_executable(节点名  src/节点名.cpp)
target_link_libraries(节点名  ${catkin_LIBRARIES})

然后回到工作空间下,注意是在工作空间下执行,执行

catkin_makec

创建一个节点,并在一个节点里订阅一个话题
/*创建一个小海龟的当前位姿信息接收*/
#include <ros/ros.h>
#include "turtlesim/Pose.h"
// 接收消息后,会进入消息回调函数,回调函数里边会对接收到的数据进行处理
void turtle_poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    // 打印接收到的消息
    ROS_INFO("Turtle pose: x:%0.3f, y:%0.3f", msg->x, msg->y);
}
int main(int argc, char **argv)
{
    ros::init(argc, argv, "turtle_pose_subscriber");// 初始化ROS节点
    ros::NodeHandle n;//这里是创建句柄
    // 创建一个订阅者,订阅的话题是/turtle1/pose的topic,poseCallback是回调函数
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10,turtle_poseCallback);
    ros::spin(); // 循环等待回调函数
    return 0;
}

在CMakelist.txt中配置

add_executable(节点名  src/节点名.cpp)
target_link_libraries(节点名 ${catkin_LIBRARIES})

 工作空间下执行

catkin_make

下面用python实现一个订阅的节点

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from turtlesim.msg import Pose
def poseCallback(msg):
    rospy.loginfo("Turtle pose: x:%0.3f, y:%0.3f", msg.x, msg.y)
def turtle_pose_subscriber():
    rospy.init_node('turtle_pose_subscriber', anonymous=True)# ROS节点初始化
    # 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)
    rospy.spin()# 循环等待回调函数
if __name__ == '__main__':
    turtle_pose_subscriber()

注意:

python程序不需要编译,但是需要添加可执行的权限,终端输入,

cd ~/ros_ws/src/功能包名/scripts

sudo chmod a+x 节点名.py



运行一个节点

rosrun   包名    可执行程序名

备注:可执行程序如果是python就直接是python文件名称,不需要再多的配置,如果是c++程序,就是CMakeLists.txt配置的那个




ros1自定义一个消息

功能包下新建一个文件夹msg

切换至msg目录下,新建一个空白的msg文件,以msg为后缀表示代表是msg文件。这里我们以Information.msg为例子说明下,把以下代码复制到刚刚创建好的msg文件里边

string company
string city
在package.xml中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
在CMakeLists.txt添加编译选项 (注意下面三行里第一行别遗漏了)
搜find_package ,然后里边加上message_generation
add_message_files(FILES Information.msg)
generate_messages(DEPENDENCIES std_msgs)
最后 工作空间下执行 catkin_make

下面分别创建一个发布和订阅节点

  发布节点   :  Information_publisher.cpp

/**
* 该例程将发布/company_info话题,消息类型是自定义的learn_topic::Information
*/
#include <ros/ros.h>
#include "learn_topic/Information.h"
int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc, argv, "company_Information_publisher");
    // 创建节点句柄
    ros::NodeHandle n;
    // 创建一个Publisher,发布名为/company_info的topic,消息类型为learn_topic::Person,队列长度10
    ros::Publisher Information_pub = n.advertise<learn_topic::Information>("/company_info", 10);
    // 设置循环的频率
    ros::Rate loop_rate(1);
    int count = 0;
    while (ros::ok())
    {
        // 初始化learn_topic::Information类型的消息
        learn_topic::Information info_msg;
        info_msg.company = "Yahboom";
        info_msg.city = "Shenzhen";
        // 发布消息
        Information_pub.publish(info_msg);
        ROS_INFO("Information: company:%s city:%s ",info_msg.company.c_str(), info_msg.city.c_str());
        loop_rate.sleep();// 按照循环频率延时
    }
    return 0;
}

订阅节点   :    Information_subscriber.cpp 

/**
* 该例程将订阅/company_info话题,自定义消息类型learn_topic::Information
*/
#include <ros/ros.h>
#include "learn_topic/Information.h"
// 接收到订阅的消息后,会进入消息回调函数处理数据
void CompanyInfoCallback(const learn_topic::Information::ConstPtr& msg)
{
    // 打印接收到的消息
    ROS_INFO("This is: %s in %s", msg->company.c_str(), msg->city.c_str());
}
int main(int argc, char **argv)
{
    ros::init(argc, argv, "company_Information_subscriber");// 初始化ROS节点
    ros::NodeHandle n;// 这里是创建节点句柄
    // 创建一个Subscriber,订阅名话题/company_info的topic,注册回调函数CompanyInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/company_info", 10,CompanyInfoCallback);
    ros::spin();// 循环等待回调函数
    return 0;
}

 修改CMakeLists.txt文件,添加以下内容,

add_executable(Information_publisher src/Information_publisher.cpp)
target_link_libraries(Information_publisher ${catkin_LIBRARIES})
add_dependencies(Information_publisher ${PROJECT_NAME}_generate_messages_cpp)

add_executable(Information_subscriber src/Information_subscriber.cpp)
target_link_libraries(Information_subscriber ${catkin_LIBRARIES})
add_dependencies(Information_subscriber ${PROJECT_NAME}_generate_messages_cpp)

 python如何使用自定义消息的,同样是一个发送者和接收者

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from learn_topic.msg import Information #导入自定义的msg
def information_publisher():
    rospy.init_node('information_publisher', anonymous=True)# ROS节点初始化
    # 创建一个Publisher,发布名为/company_info的topic,消息类型为learn_topic::Information,队列长度6
    info_pub = rospy.Publisher('/company_info', Information, queue_size=6)
    rate = rospy.Rate(10) #设置循环的频率
    while not rospy.is_shutdown():
    # 初始化learn_topic::Information 类型的消息
        info_msg = Information()
        info_msg.company = "Yahboom";
        info_msg.city = "Shenzhen";
        info_pub.publish(info_msg)# 发布消息
        rospy.loginfo("This is %s in %s.", info_msg.company, info_msg.city)# 打印发布消息
        rate.sleep()# 按照循环频率延时
if __name__ == '__main__':
    try:
        information_publisher()
    except rospy.ROSInterruptException:
        pass
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from learning_topic.msg import Information #导入自定义的msg
def CompanyInfoCallback(msg):
    rospy.loginfo("company: name:%s city:%s ", msg.company, msg.city)#打印订阅接收到信息
def Infomation_subscriber():
    rospy.init_node('Infomation_subscriber', anonymous=True)# ROS节点初始化
    # 创建一个Subscriber,订阅名为/company_info的topic,注册回调函数personInfoCallback
    rospy.Subscriber("/company_info", Information, CompanyInfoCallback)
    rospy.spin()# 循环等待回调函数
if __name__ == '__main__':
    Infomation_subscriber()

 两个文件保存后,需要给定执行权限, 

cd ~/ros_ws/src/learn_topic/scripts
sudo chmod a+x Information_publisher.py
sudo chmod a+x Information_subscriber.py

备注: 
from learn_topic.msg import Information
learn_topic表示功能包、msg表示功能包下的msg文件夹,Infomation表示自定义msg文件的名字


Launch相关功能包下创建一个文件夹 叫launch
mkdir launch
再回到工作空间目录下进行编译,  
cd ~/ros_ws
catkin_make
然后在launch文件夹下,新建一个文件,文件名是turtle_node.launch,把以下内容负责到里边

备注:

pkg :  包名 

type  :   运行节点的可执行程序的名字 ,这个是add_executable  第一个参数定义得名字

name:节点的名字,不一定要与程序中定义节点名字一样,可以任意命名,这个名字就是通过                   rostopic list 看到的名字

<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="turtle"/>  
</launch>
roslaunch learn_launch turtle_node.launch

同时launch文件还可以加载运行launch文件

launch文件中,不仅可以运行节点,还可以加载运行launch文件,也就是嵌套使用,这里需要用到的标签是。常用的格式为,

<include file=”$(find package_name)/launch/launch_file_name”/>

 package_name:表示launch文件所在的功能包

launch_file_name:表示需要运行的launch文件的文件名字

<launch>
    <include file="$(find 包名)/launch/launch名.launch"/>
    <node pkg="learn_topic" type="turtle_pose_subscriber" name="turtle_pose" 
    output="screen"/>  
</launch>

 这里在node这里启动的时候加入了一个参数output,因为我们是想要在终端打印这个信息的,所以是输出到屏幕screen还有两个值分别是log输出到日志,none无输出

launch文件加载参数

在launch文件中,有两个变量是表示参数的,分别是arg和param,它们的含义如下:

  • name:参数的名称
  • default:参数的默认值
  • <launch>
        <arg name="r_value" default="100"/>
        <arg name="g_value" default="0"/>
        <arg name="b_value" default="100"/>
        <node pkg="turtlesim" type="turtlesim_node" name="turtle">
            <param name="/background_r" value="$(arg r_value)"/>  
            <param name="/background_g" value="$(arg g_value)"/> 
            <param name="/background_b" value="$(arg b_value)"/> 
        </node>
    </launch> 

    我们还可以在启动的时候,在命令行修改rgb的值,只要带上参数即可,例如,终端输入,

  • roslaunch  包名  launch名.launch   b_value:=2

    可以看出,我们在启动命令的时候,把b_value的值修改成2,然后传入进去。这里的参数是怎么传递的呢?在node标签里边,我们设置了三个参数,分别是/background_r、/background_g和/background_b,它们value的值,分别是$(arg r_value)、$(arg g_value)和$(arg b_value);再看看r_value、g_value和b_value的默认值,分别是上边arg标签里边的100、0和100,这就很明了了:我们在arg里定义的值,然后在arg里定义的值传给param里的value。在引用的时候加上$(arg g_value)即可,当然,你也可以不用,也就是写成把那么这样,这个/background_g的参数值就是固定的255了。

话题名称映射

在实际的开发过程中,原本预设定话题的名字往往需要根据其他节点的话题名字进行修改,源码修改比较麻烦,C++版本的代码修改完还需要编译,比较麻烦,但在launch文件中,用标签即可实现重映射话题名字,把预设定的话题的名字映射成其它的,用法如下,

<remap from="original_topic" to="remapped_topic" />

 成功运行后,输入rostopic list看看,终端输入, 发现话题得名称已经换成了映射后得名字

<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="turtle">
        <remap from="/turtle1/cmd_vel" to="/ctrl_vel"/>
    </node>  
</launch>

 这时候,原来的/turtle1/cmd_vel没有了,映射成/ctrl_vel了,这是因为我们在launch文件,重新映   射了话题, 


launch文件中使用条件语句

我们在launch文件中,可以加上条件判断来决定是否要启动节点程序,条件判断在launch文件中由ifunless来控制,具体的用法举例说明,在launch文件夹新建一个文件命名为condition_ctrl_turtle.launch,程序运行后,根据实际的参数,进行判断是否启动某节点

<launch>
    <arg name="ctrl_node" default="true"/>
    <node pkg="turtlesim" type="turtlesim_node" name="turtle"/>  
    <node pkg="turtlesim" type="turtle_teleop_key" name="turtle_ctrl" if="$(eval arg('ctrl_node') == true)"/>
</launch>
roslaunch learn_launch condition_ctrl_turtle.launch   ctrl_node:=false    
运行时候通过语句末尾添加一些参数,决定

 launch文件中有个组的概念,标签是,它可以将指定的节点nodes组织起来,将几个nodes放进同一个namespace中。namespace是命名空间,作用是避免名称冲突,ros系统中不允许出现相同的节点名字。比如说,我们想要在在一个终端打开两个小海龟的节点,如果没有命名空间,直接启动的话,是会产生冲突导致程序退出的,因此,我们需要在launch文件中,加上命令空间namespace,相当于在相同节点前再添加一个标识来区分两个节点

我们在group中加上了ns,即可为所有节点名前添加命名空间

<launch>
    <group ns="robot1">
        <node pkg="turtlesim" type="turtlesim_node" name="turtle"/>  
    </group>
    <group ns="robot2">
        <node pkg="turtlesim" type="turtlesim_node" name="turtle"/>  
    </group>
</launch>

rosnode list


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值