首页 > 编程语言 >5.编写ROS程序

5.编写ROS程序

时间:2024-09-22 14:51:39浏览次数:11  
标签:turtle ROS 程序 person msg 编写 vel ros turtlesim

1. 发布者Publisher的编程实现

1.1. 创建功能包
catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

1.2. 创建发布者代码(C++)
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

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

    //创建节点句柄
    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);

    int count = 0;
    while (ros::ok())
    {
        // 初始化geometry_msgs::Twist类型的消息
        geometry_msgs::Twist vel_msg;
        vel_msg.linear.x = 0.5;
        vel_msg.angular.z = 0.2;

        // 发布消息
        turtle_vel_pub.publish(vel_msg);
        ROS_INFO("Publish turtle velocity command[%0.2f m/s,%0.2f rad/s]",vel_msg.linear.x,vel_msg.angular.z);

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

    return 0;
    
}
1.3. 配置发布者代码编译规则
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
1.4. 编译并运行发布者
catkin_make

  1. 运行roscore
roscore
  1. 运行海龟仿真器
rosrun turtlesim turtlesim_node
  1. 设置环境变量
source devel/setup.bash
  1. 运行自己功能包定义
rosrun learning_topic velocity_publisher

2. 订阅者Subscriber的编程实现

2.1. 订阅代码
#include <ros/ros.h>
#include "turtlesim/Pose.h"

void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    // 将接受到的消息打印出来
    ROS_INFO("Turtle pose: x:%0.6f,y:%0.6f",msg->x,msg->y);
}

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

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

    // 创建一个Subsciber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose",10,poseCallback);

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

    return 0;
}
2.2. 配置订阅代码编译规则
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
2.3. 编译代码
catkin_make

2.4. 运行代码
roscore
rosrun turtlesim turtlesim_node
source devel/setup.bash
rosrun pose_subscriber pose_subscriber
rosrun turtlesim turtle_teleop_key

3. 话题消息的定义与使用

3.1. 创建msg文件夹

3.2. 数据接口定义

创建Person.msg文件并写入内容

注意这里只能一个空格

string name
uint8 sex
uint8 age

uint8 unkown = 0
uint8 male   = 1
uint8 female = 2

3.3. 在package.xml中添加功能包依赖
  <build_export_depend>message_generation</build_export_depend>
  <exec_depend>message_runtime</exec_depend>

3.4. 在CMakeList.txt添加编译选项
  1. 添加依赖包

  1. 添加消息定义
add_message_file(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)

  1. 添加运行依赖
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime

  1. 完成编译

3.5. 创建发布者代码
#include <ros/ros.h>
#include "learning_topic/Person.h"

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

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

    // 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度为10
    ros::Publisher  person_info_pub = n.advertise<learning_topic::Person>("/person_info",10);

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

    int count = 0;

    while (ros::ok())
    {
        // 初始化learning_topic::Person类型的消息
    	learning_topic::Person person_msg;
		person_msg.name = "Tom";
		person_msg.age  = 18;
		person_msg.sex  = learning_topic::Person::male;

        // 发布消息
		person_info_pub.publish(person_msg);

       	ROS_INFO("Publish Person Info: name:%s  age:%d  sex:%d", 
				  person_msg.name.c_str(), person_msg.age, person_msg.sex);

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

    return 0;

}
3.6. 订阅者代码
#include <ros/ros.h>
#include "learning_topic/Person.h"

// 接受订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
    // 将接受到的消息打印出来
    ROS_INFO("Subcribe Person Info: name:%s age:%d sex:%d", msg->name.c_str(), msg->age, msg->sex);
}

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

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

     // 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

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

    return 0;
}
3.7. 添加编译规则
add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)

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

3.8. 运行代码
rosrun learning_topic person_subscriber
rosrun learning_topic person_publisher

4. 客户端Client的编程实现

实现客户端的流程:

  1. 初始化ROS节点;
  2. 创建一个Client实例
  3. 发布服务请求数据;
  4. 等待Server处理之后的应答结果;
4.1. 创建功能包
catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

4.2. 编写代码
#include <ros/ros.h>
#include <turtlesim/Spawn.h>

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

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

    // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
    ros::service::waitForService("/spawn");
    ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");

    // 初始化turtlesim::Spawn的请求数据
    turtlesim::Spawn srv;
    srv.request.x = 2.0;
    srv.request.y = 2.0;
    srv.request.name = "turtle2";

    // 请求服务调用
    ROS_INFO("Call service to spwan turtle[x:%0.6f,y:%0.6f,name:%s]",
            srv.request.x, srv.request.y, srv.request.name.c_str());

    add_turtle.call(srv);

    // 显示服务调用结果
    ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());

    return 0;
}
4.3. 配置编译规则
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

4.4. 编译代码

4.5. 程序运行
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_spawn 

5. 服务端Service编程实现

5.1. 编写代码
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Trigger.h>

ros::Publisher  turtle_vel_pub;
bool pubCommand = false;

// service回调函数,输入参数req,输出参数res
bool commandCallback(std_srvs::Trigger::Request &req,
                     std_srvs::Trigger::Response &res)
{
    pubCommand = !pubCommand;

    // 显示请求数据
    ROS_INFO("Publish turtle velocity commadn [%s]", pubCommand==true?"Yes":"No");

    // 设置反馈数据
    res.success = true;
    res.message = "Change turtle command state!";

    return true;
}

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

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

    // 创建一个名为/turtle_command的server,注册回调函数commandCallback
    ros::ServiceServer command_service = node.advertiseService("/turtle_command",commandCallback);

    // 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度为10
    turtle_vel_pub = node.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);

    // 循环等待回调函数
    ROS_INFO("Ready to receive turtle command.");

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

    while (ros::ok())
    {
        // 查看一次回调函数队列
        ros::spinOnce();

        // 如果标志为true,则发布速度指令
        if (pubCommand)
        {
            geometry_msgs::Twist vel_msg;
            vel_msg.linear.x = 0.5;
            vel_msg.angular.z = 0.2;
            turtle_vel_pub.publish(vel_msg);
        }

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

}
5.2. 配置编译规则
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
5.3. 编译代码

5.4. 程序运行
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server
rosservice call /turle_command "{}"

标签:turtle,ROS,程序,person,msg,编写,vel,ros,turtlesim
From: https://blog.csdn.net/m0_62236205/article/details/142301974

相关文章

  • 帝国cms网站建站程序安装教程
    帝国CMS网站建站程序安装教程工具/原料已搭建好PHP环境的服务器或者本地测试环境。帝国CMS建站程序安装包。方法/步骤下载帝国CMS安装包百度搜索“帝国CMS官网”,进入帝国CMS官网。找到下载页面,根据需要选择对应的版本下载程序安装包。解压并上传文件解压帝国CMS......
  • Java异常处理:给程序罩一层保险
    编译器强制要求程序员为检查异常做预处理工作——捕获异常并处理或者抛出异常,否则编译器就会提示错误。常见的这类异常有SQLException、IOException和ClassNotFoundException。编译器不会提示非检查异常,也不要求在程序中处理这些异常。但通常情况下,程序员应该对这些异常有所防范......
  • 推荐一个很酷的脚本工具,几行代码,就能编写有用的 shell 脚本,月猛增 7.4 K Star太牛逼了
     今天给大家介绍的是gum,它是一个很酷的脚本工具。项目介绍gum是一个很棒的脚本工具,提供了高度可配置,随时可用的实用程序,只需几行代码,就能编写有用的shell脚本。让我们构建一个简单的脚本来创建提交。由下面的代码开始:#!/bin/sh询问gumchoose的提交类型:gum ch......
  • 打卡信奥刷题(780)用Scratch图形化工具信P6414[普及组/提高组] [COCI2014-2015#1] PROSJ
    [COCI2014-2015#1]PROSJEK题目描述有一个数列aaa,现在按照下列公式求出一个数列bb......
  • 基于微信小程序的学生公寓电费信息管理系统+ssm(lw+演示+源码+运行)
    基于微信小程序的学生公寓电费信息管理系统摘要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,微信小程序被用户普遍使用,为方便用户能够可以随时进行小程序的相应信息内容的......
  • python+flask计算机毕业设计家庭财务管理系统APPy(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今社会,随着家庭经济活动的日益复杂和多元化,个人及家庭对于财务管理的需求日益增长。传统的手工记账方式已难以满足现代家庭对财务透明......
  • python+flask计算机毕业设计基于物联网技术的水质实时监测系统设计与实现(程序+开题+论
    文件加密系统的设计与实现tp835本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着工业化进程的加速和人口的不断增长,水资源的保护与监测日益成为全球关注的重大课题。水质污染问题不仅......
  • python+flask计算机毕业设计快递代取小程序(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今社会,随着电子商务的蓬勃发展,快递业务量急剧增长,成为了人们日常生活中不可或缺的一部分。然而,随之而来的“取件难”问题也日益凸显,尤......
  • python+flask计算机毕业设计+Vue的残疾人再就业系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着社会经济的快速发展与人口老龄化的加剧,残疾人群体作为社会的重要组成部分,其就业问题日益凸显。传统就业市场往往因信息不对称、技能不......
  • python+flask计算机毕业设计+vue的服装售后服务系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着电子商务的蓬勃发展,服装行业作为其中的重要组成部分,其售后服务质量已成为影响消费者购买决策的关键因素之一。传统的服装售后服务模式......