天天看点

ROS实践-工作空间的使用

工作空间的创建

ros里的工作空间就相当于C++的项目工程,都是用来放置代码的地方。

而ros默认使用的是catkin编译系统,等同与c++的cmake编译系统,编译的方式有所区别,文件的放置有所区别。

典型的空间必有这三个文件夹:src代码空间-存储功能包的源码、build编译空间-存储编译工程中的中间文件、devel开发空间-放置编译生成的可执行文件。

随便建一个你想取名的文件夹,在里面创建src文件夹,使用catkin_init_workspace命令初始化工作空间,会自动生成CMakeLists.txt,个人理解CMakeLists.txt就相当于编译规则,你编译的时候就会按照其中的内容去编译,用命令去初始化工作空间生成CMakeLists.txt就相当于给一个空白空间生成了编译的手段,让他能够catkin编译。

虽然现在我们src源码空间什么都没有写,但是回到上层文件夹用catkin_make命令编译还是能够编译,会自动生成build和devel两个文件夹和其中的文件,这都是CMakeLists.txt中初始就有的。其中devel文件夹中产生了几个setup.bash的环境变量设置脚本,使用source命令运行脚本,工作空间中的环境变量才能生效。个人理解配置环境变量就是让系统找到你写的程序的路径,不然系统只会运行系统文件,根本不知道你的程序的存在。

这就是最基本的工作空间(空的)的创建。

src中功能包的创建

首先进入src中,使用catkin_create_pkg 功能包名 所需依赖功能包名

来创建功能包,生成的功能包中已经包含package.xml-功能包清单,描述功能包属性的信息和CMakeLists.txt-记录功能包的编译规则。

实践-话题编程

话题是ros节点间通信的一种重要方式,发布消息者为发布者,接受消息者为订阅者,两者并不了解彼此的存在,所以时效性不强,无回复,相当于写信,是单向异步通信。这种通信方式常常是用在传感器数据的传输,数据不停的传输,不需要反馈。

在刚刚创建好的工作空间的src文件夹中使用catkin_create_pkg learning_communication std_msgs rospy roscpp命令创建名为learning_communication的功能包。

它创建的功能包会帮你配置好初始的环境,有include文件夹、src文件夹、package.xml和CMakeLists.txt。

在src中写talker.cpp(发布者)和listener.cpp(订阅者)。

(1)talker.cpp:

/**
 * 该例程将发布chatter话题,消息类型String
 */

#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv)
{
  // ROS节点初始化
  ros::init(argc, argv, "talker");

  // 创建节点句柄
  ros::NodeHandle n;

  // 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

  // 设置循环的频率
  ros::Rate loop_rate(10);

  int count = 0;
  while (ros::ok())
  {
        // 初始化std_msgs::String类型的消息
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

        // 发布消息
    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);

        // 循环等待回调函数
    ros::spinOnce();

        // 按照循环频率延时
    loop_rate.sleep();
    ++count;
  }

  return 0;
}
~                   
           

(2)listener.cpp:

/**
 * 该例程将订阅chatter话题,消息类型String
 */

#include "ros/ros.h"
#include "std_msgs/String.h"

// 接收到订阅的消息后,会进入消息回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  // 将接收到的消息打印出来
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  // 初始化ROS节点
  ros::init(argc, argv, "listener");

  // 创建节点句柄
  ros::NodeHandle n;

  // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  // 循环等待回调函数
  ros::spin();

  return 0;
}

           

然后在功能包CMakeLists.txt中设置需要编译的代码和生成的可执行文件

add_executable(talker src/talker.cpp)

add_executable(listener src/listener.cpp)

设置库连接

target_link_libraries(talker ${catkin_LIBRARIES})

target_link_libraries(listener ${catkin_LIBRARIES})

设置依赖

#add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)

#add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)

这时,功能包的编写就已经完成。

退到大文件夹下,编译catkin_make。

配置环境变量 source ./devel/setup.bash

先roscore,再rosrun learning_communication talker,最后rosrun learning_communication listener。

效果如图:

ROS实践-工作空间的使用

完美收工!!!!!

继续阅读