ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ROS 基础知识(一)

2021-12-29 19:59:21  阅读:120  来源: 互联网

标签:include catkin ROS 创建 基础知识 add ros


ROS基础目录

工作空间

src 代码空间

build 编译空间

devel 开发空间

install 安装控件

创建工作空间

创建工作空间是在src目录下进行catkin_init_workspace

mkdir -p ~/catkin_ws/src 	// 创建目录  -p 一次行创建多级目录
cd ~/catkin_ws/src			// 切换到 ~/catkin_ws/src	 目录下
catkin_init_workspace		// 初始化工作空间

编译工作空间

编译工作空间要在根目录下

cd ~/catkin_ws/				// 切换到工作空间根目录
catkin_make					// 编译

设置环境变量

仅在当前terminal中有效的设置方法

source devdl/setup.bash		// 这一步是在根目录下执行

确定当前环境变量是否设置成功

echo $ROS_PACKAGE_PATH

输出

/home/luo/ws/catkin_ws/src:/opt/ros/melodic/share

环境变量通过 : 进行分割 如果自己的目录在环境变量中,既是设置成功,可以发现后加入的环境变量在前面。

永久有效的方法

前面的方法在新开的terminal中,刚刚设置的环境变量还是不存在的。如果想在新打开的terminal中依然存在刚设置的环境变量,需要修改~目录下的.bashrc。方法如下

nano ~/.bashrc

在.bashrc 最后加入

source ~/ws/catkin_ws/devel/setup.bash
source ~/.bashrc				// 更新环境变量

验证 环境变量 是否成功设置,新开一个terminal,

echo $ROS_PACKAGE_PATH

查看输出的路径中是否有刚刚自己添加的路径。

在环境变量中 筛选有用信息

env |grep ROS_PACKAGE_PATH

查看环境变量中和ROS_PACKAGE_PATH相关的信息

创建功能包

创建功能包要在src下面

catkin_create_pkg learning_communication std_msgs rospy roscpp

其中catkin_create_pkg是指令

learning_communication功能包的名字

std_msgs rospy roscpp 是依赖环境 正常都要带上

编译功能包

返回到根目录

cd ..

编译

catkin_make

注意事项:同一个工作空间下,不可以存在相同的功能包

​ 不同的工作空间下,可以存在相同的功能包

查找功能包

rospack find roscpp_tutorials

返回的是功能包的路径

ROS通信机制

1、话题编程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjiF89gD-1640778615234)(D:\笔记文件夹\ROS基础(2).assets\image-20211229105628607-16407466072741.png)]

  1. 创建发布者

  2. 创建订阅者

  3. 添加编译选项

  4. 运行可执行程序

创建发布者

/**
 * 该例程将发布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;
}

CMakeLists.txt 中文件修改

生产可执行文件 talker 生成到 devel/lib/node名称下/talker,之后通过rosrun 对其进行执行

add_executable(talker src/talker.cpp)

如果cpp中用到第三方插件,需要在这里进行target_link 链接到第三方库文件,现在链接的库是catkin的基础库

 target_link_libraries(talker  ${catkin_LIBRARIES} )

创建接收者

自己写的程序

#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::init(argc,argv,"lensener");
   ros::NodeHandle n;

   ros::Subscriber sub = n.subscribe("chatter1",1000,chatterCallback);

    ros::spin();


    return 0;
}

程序历程

/**
 * 该例程将订阅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 中文件修改

生产可执行文件 talker 生成到 devel/lib/node名称下/talker,之后通过rosrun 对其进行执行

add_executable(lensener src/lensener.cpp)

如果cpp中用到第三方插件,需要在这里进行target_link 链接到第三方库文件,现在链接的库是catkin的基础库

 target_link_libraries(lensener  ${catkin_LIBRARIES} )

此处出现的问题:

当先开启 subscribe,再启动Publisher 时, 发布的前两包信息会被丢弃 这个是什么原因?

  1. 定义msg文件
  2. 再package.xml中添加功能包依赖
  3. 再CMakeList.txt中添加编译

自定义消息结构

  1. 在功能包下新建 msg文件夹

    新建文件Person.msg

    string name
    uint8 sex
    uint8 age
    
    uint8 unknown = 0
    uint8 male =1
    uint8 female =2
    
  2. 在package.xml 中加入

      <build_depend> message_generation</build_depend>
      <exec_depend>message_runtime</exec_depend>
    
  3. CMakeList中加入

    1. find_package(catkin REQUIRED COMPONENTS
        roscpp
        rospy
        std_msgs
        message_generation
      )
      
    2. ## Generate messages in the 'msg' folder
      add_message_files(
        FILES
        Person.msg
        # Message2.msg
      )
      
    3. ## Generate added messages and services with any dependencies listed here
      generate_messages(
        DEPENDENCIES
        std_msgs
      )
      
    4. catkin_package(
      #  INCLUDE_DIRS include
      #  LIBRARIES learning_communication
       CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
      #  DEPENDS system_lib
      )
      

      在创建完成后,编译 可以通过

      rosmsg show Person 来验证创建的是否正确
      

2、服务编程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0t52qGJO-1640778615236)(D:\笔记文件夹\ROS基础 (2).assets\image-20211229153801254-16407634850601.png)]

  1. 创建服务器
  2. 创建客户端
  3. 添加编译选项
  4. 运行可执行程序

定义srv文件

  1. 定义srv文件

  2. 在package.xml中添加功能包依赖

      <build_depend> message_generation</build_depend>
      <exec_depend>message_runtime</exec_depend>
    
  3. 在CMakeList.txt中修改 和自定义添加编译依赖 1、2 相同 3 是特有的

  4. find_package(catkin REQUIRED COMPONENTS
      roscpp
      rospy
      std_msgs
      message_generation
    )
    
  5. catkin_package(
    #  INCLUDE_DIRS include
    #  LIBRARIES learning_communication
     CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
    #  DEPENDS system_lib
    )
    
  6. ## Generate services in the 'srv' folder
    add_service_files(
      FILES
      AddTwo.srv
      # Service2.srv
    )
    
  7. 生成可支持 文件

    add_executable(server src/server.cpp)
    
  8. 测试生成文件是否可用

    启动 roscore rosrun

注意

在vscode中编程为了在编程过程中能够讲新建的srv文件引入,需要在 src/.vscode/c_cpp_properties.json 文件下 includePath 下面加入

    "includePath": [
        "/opt/ros/melodic/include/**",
        "/home/luo/ws/catkin_ws/src/learning_communication/include/**",
        "/usr/include/**",
        "/home/luo/ws/catkin_ws/devel/include/learning_communication**"				// 这行是新加入的,包含的新生成的srv文件
      ],

创建一个服务器

  1. 初始化ROS节点
  2. 创建Server实例
  3. 循环等到服务请求,进入回调函数
  4. 在回调函数中完成服务功能的处理,并反馈应答数据
#include "ros/ros.h"
#include "learning_communication/AddTwo.h"

// service回调函数,输入参数req,输出参数res
bool add(learning_communication::AddTwo::Request  &req,
         learning_communication::AddTwo::Response &res)
{
  // 将输入参数中的请求数据相加,结果放到应答变量中
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  
  return true;
}

int main(int argc, char **argv)
{
  	// ROS节点初始化
    ros::init(argc,argv,"add_two_inis_server");
    
	// 创建节点句柄
    ros::NodeHandle n;
	
	// 创建一个名为add_two_ints的server,注册回调函数add()
    ros::ServiceServer service = n.advertiseService("add_two_inis",add);
	
	// 循环等待回调函数
    ROS_INFO("Ready to add two ints.");
    ros::spin();

    return 0;
}

客户端程序

#include "learning_communication/AddTwo.h"
#include "ros/ros.h"
#include <cstdlib>

int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc,argv,"add_two_ints_client");
    
    // 从终端命令行获取两个加数
    if (argc !=3)
    {
        ROS_INFO("usage :add two ints client X Y");
        return 1;
    }
    
    // 创建节点句柄
    ros::NodeHandle n;
    
	// 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoInts
    ros::ServiceClient client = n.serviceClient<learning_communication::AddTwo>("add_two_inis_server");
	
	// 创建learning_communication::AddTwoInts类型的service消息
    learning_communication::AddTwo srv;
    srv.request.a = atoll(argv[1]);
    srv.request.b = atoll(argv[2]);

	// 发布service请求,等待加法运算的应答结果
    if(client.call(srv))
    {
        ROS_INFO("Sum: %ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_INFO("Failed to call service add_ two_ints");
        return 1;
    }
    return 0;
}

编译代码

add_executable(server src/server.cpp)						// 编译代码生成可执行文件
target_link_libraries(server  ${catkin_LIBRARIES} )			// 设置链接库
add_dependencies(server ${PROJECT_NAME}_gencpp)				// server  需要多加的一句  设置依赖

add_executable(client src/client.cpp)
target_link_libraries(client  ${catkin_LIBRARIES} )
add_dependencies(client ${PROJECT_NAME}_gencpp)				

标签:include,catkin,ROS,创建,基础知识,add,ros
来源: https://blog.csdn.net/Diiiiiiiiiiiiiiii/article/details/122223420

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有