ROSアプリケーション開発エントリーサービスのデータ定義と使用

ROSはRobotOperating Systemの略で、ROSアプリケーション開発の紹介、サービスデータの定義と使用について紹介します。クライアントとサーバー間の通信はサービスデータを使用します。この記事では、最初にサービスデータを定義します。コンパイルが成功したら、サーバーとクライアントを使用して検証します。クライアントはrosservice呼び出しを直接使用することもできるため、クライアントはプログラムを必要としません。テスト検証は、最初にC ++コード、次にpythonコードです。また、使い慣れたコードのみを確​​認することもできます。

関数パッケージの作成

この記事は 、ROSアプリケーション開発の概要 におけるクライアントクライアントのプログラミングの続きです。この記事で関数パッケージを作成した場合は、ここでは必要ありません。このセクションをスキップしてください。

ROSのワークスペースは、 記事に設立されたROSの開発と応用の準備:ワークスペースを作成します。今、機能的なパッケージを作成します。:

cd〜 / catkin_ws / src

catkin_create_pkg Learning_service std_msgs roscpp rospygeometry_msgsturtlesim
 

カスタムサービスデータ

プロジェクトパッケージディレクトリの下に新しいディレクトリsrvを作成します

cd〜 / catkin_ws / src / Learning_service

mkdir srv

cd srv

次に、新しいPerson.srvファイルを作成します

nano Person.srv

ファイルの内容は次のとおりです。

string name
uint8  age
uint8  sex

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2

---
string result

このファイルの特徴を見てみましょう。

 

要求データと応答データは--- 3本の横線-で区切られ、上部が要求データ、下部が応答データです。

上記はデータを送信するためのものであり、割り当てられていないデータ型はデータ型であり、割り当てられた値は列挙型クラスである可能性があるため、3つの変数string name、uint8 age、uint8sexを入力する必要があります

以下は応答データです、ここは単なる文字列です

 

プロジェクトパッケージディレクトリに戻り、package.xmlを開いて編集します。

 cd〜 / catkin_ws / src / Learning_service

nano package.xml

次の2行を追加します。

<build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>


追加された位置は、<export>の前のコメントの上にある次の位置を参照します。

 <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>turtlesim</exec_depend>
 
  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
 
  <!-- The export tag contains other, unspecified, tags -->
  <export>


次に、CMakeLists.txtを開いて編集します。合計3つです。

nano CMakeLists.txt

まず、find_packageにmessage_generationを
追加し、次のように追加します。

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)

 次のコードを追加します。これは2行としても使用できます。

add_service_files(
  FILES
  Person.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

追加場所は次のとおりです。 

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   geometry_msgs#   std_msgs
# )

add_service_files(
  FILES
  Person.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################

catkin_packageで、行CATKIN_DEPENDS Geometry_msgs roscpp rospy std_msgs turtlesimのコメントを解除し、message_runtimeを追加し
て次の効果持たせます。

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_topic
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
#  DEPENDS system_lib
)

これら2つのファイルを変更した後、ワークスペースでコンパイルします。

コンパイルは〜/ catkin_wsディレクトリに戻る必要があります

cd〜 / catkin_ws

catkin_make

コンパイルが成功すると、サービスデータが定義され、準備が整います。

コンパイル情報の最終段階を見てください

Scanning dependencies of target learning_service_generate_messages_py
[ 40%] Generating Python code from SRV learning_service/Person
[ 45%] Generating Python srv __init__.py for learning_service
[ 45%] Built target turtle_command_server
Scanning dependencies of target learning_service_generate_messages_eus
[ 50%] Generating EusLisp code from learning_service/Person.srv
[ 54%] Generating EusLisp manifest code for learning_service
[ 54%] Built target learning_service_generate_messages_py
Scanning dependencies of target learning_service_generate_messages_nodejs
[ 59%] Generating Javascript code from learning_service/Person.srv
[ 59%] Built target learning_service_generate_messages_nodejs
Scanning dependencies of target learning_service_generate_messages_cpp
[ 63%] Generating C++ code from learning_service/Person.srv
[ 63%] Built target learning_service_generate_messages_cpp
Scanning dependencies of target learning_service_generate_messages_lisp
[ 68%] Generating Lisp code from learning_service/Person.srv
[ 68%] Built target learning_service_generate_messages_lisp
[ 72%] Built target learning_topic_generate_messages_nodejs
[ 77%] Built target learning_topic_generate_messages_cpp
[ 86%] Built target learning_topic_generate_messages_eus
[ 95%] Built target learning_topic_generate_messages_py
[100%] Built target learning_topic_generate_messages_lisp
[100%] Built target learning_topic_generate_messages
[100%] Built target learning_service_generate_messages_eus
Scanning dependencies of target learning_service_generate_messages
[100%] Built target learning_service_generate_messages

複数の言語に対応できるようです。

c ++はソースコードを確認します

サービスデータを使用して検証するには、サーバーとクライアント用に2つのプログラムが必要であり、それらをプロジェクトディレクトリのsrcディレクトリに配置します。

srcディレクトリに移動し、それぞれperson_client.cppファイルとperson_server.cpp.cppファイルを作成します。

cd〜 / catkin_ws / src / Learning_service / src

nano person_client.cpp

ファイルの内容は次のとおりです。

/**
 * 该例程将请求/show_person服务,服务数据类型learning_service::Person
 */

#include <ros/ros.h>
#include "learning_service/Person.h"

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

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

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

    // 初始化learning_service::Person的请求数据
        learning_service::Person srv;
        srv.request.name = "Tom";
        srv.request.age  = 20;
        srv.request.sex  = learning_service::Person::Request::male;

    // 请求服务调用
        ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", 
                         srv.request.name.c_str(), srv.request.age, srv.request.sex);

        person_client.call(srv);

        // 显示服务调用结果
        ROS_INFO("Show person result : %s", srv.response.result.c_str());

        return 0;
};

nano person_server.cpp

ファイルの内容は次のとおりです。

/**
 * 该例程将执行/show_person服务,服务数据类型learning_service::Person
 */
 
#include <ros/ros.h>
#include "learning_service/Person.h"

// service回调函数,输入参数req,输出参数res
bool personCallback(learning_service::Person::Request  &req,
                                learning_service::Person::Response &res)
{
    // 显示请求数据
    ROS_INFO("Person: name:%s  age:%d  sex:%d", req.name.c_str(), req.age, req.sex);

        // 设置反馈数据
        res.result = "OK";

    return true;
}

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

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

    // 创建一个名为/show_person的server,注册回调函数personCallback
    ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);

    // 循环等待回调函数
    ROS_INFO("Ready to show person informtion.");
    ros::spin();

    return 0;
}


2つのファイルの準備ができました。

cmakeファイルを構成する

〜/ catkin_ws / src / Learning_service /ディレクトリにCMakeLists.txtファイルがあり、このファイルを変更する必要があります

cd〜 / catkin_ws / src / Learning_service /

nano CMakeLists.txt 

このファイルに次の行を追加します。

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

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

追加された位置は、ビルドセクションの終わりです。## install ##の前にある次の位置を参照してください。その後、前のクライアントとサーバーは、それぞれの後に2行を追加します。

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})

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

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

#############
## Install ##
#############

保存して終了

これでコンパイルと構成は完了です。

テストをコンパイルして実行します

コンパイルは〜/ catkin_wsディレクトリに戻る必要があります

cd〜 / catkin_ws

catkin_make

コンパイル後に一度ソースする必要があります。

ソースdevel / setup.bash

コンパイルでエラーが発生した場合は、エラーを排除する必要があり、コンパイルの完了後にテストが実行されます。

ターミナルを開き、rosを起動し、実行します

roscore

別の端末を開き、サーバーを起動して実行します

rosrun Learning_service person_server

別のターミナルを開き、クライアントを起動します。

rosrun Learning_service person_client

実際、rosserviceをテスト用のクライアントとして直接使用することもできます

rosservice call / show_person leon 12 2

または

leon @ ubuntu:〜$ rosservice call / show_person "name: 'Leon'
age:50
sex:20" 
プログラムの実行結果は次のとおりです。クライアントは最初にクライアントを2回実行し、次にrosservice呼び出しを2回実行し、次にクライアントを再度実行します。

c ++検証は成功します。

Python検証ソースコード

サービスデータを検証するには、サーバー側とクライアント側の2つのプログラムが必要であり、プロジェクトディレクトリのscriptsディレクトリに配置します。

スクリプトディレクトリに移動し、ファイルperson_client.pyとperson_server.pyをそれぞれ作成します。そうでない場合は、ファイルを作成します(mkdirスクリプト)。

〜/ catkin_ws / src / Learning_service / scripts

nano person_server.py

ファイルの内容は次のとおりです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将执行/show_person服务,服务数据类型learning_service::Person

import rospy
from learning_service.srv import Person, PersonResponse

def personCallback(req):
	# 显示请求数据
    rospy.loginfo("Person: name:%s  age:%d  sex:%d", req.name, req.age, req.sex)

	# 反馈数据
    return PersonResponse("OK")

def person_server():
	# ROS节点初始化
    rospy.init_node('person_server')

	# 创建一个名为/show_person的server,注册回调函数personCallback
    s = rospy.Service('/show_person', Person, personCallback)

	# 循环等待回调函数
    print "Ready to show person informtion."
    rospy.spin()

if __name__ == "__main__":
    person_server()


nano person_client.py

ファイルの内容は次のとおりです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将请求/show_person服务,服务数据类型learning_service::Person

import sys
import rospy
from learning_service.srv import Person, PersonRequest

def person_client():
	# ROS节点初始化
    rospy.init_node('person_client')

	# 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
    rospy.wait_for_service('/show_person')
    try:
        person_client = rospy.ServiceProxy('/show_person', Person)

		# 请求服务调用,输入请求数据
        response = person_client("Tom", 20, PersonRequest.male)
        return response.result
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

if __name__ == "__main__":
	#服务调用并显示调用结果
    print "Show person result : %s" %(person_client())


テストを実行する

Pythonはコンパイルする必要はありませんが、実行可能ファイルとして設定する必要があるためです

chmod + x * .py

ターミナルを開き、rosを起動し、実行します

roscore

最初のソース:

ソース〜/ catkin_ws / devel / setup.bash

別の端末を開き、サーバーを起動して実行します

rosrun Learning_service person_server.py 

別のターミナルを開き、クライアントを起動します。

rosrun Learning_service person_client.py

クライアント認証では、rosservice呼び出しを直接使用することもできます

rosservice call / show_person leon 12 2

または

leon @ ubuntu:〜$ rosservice call / show_person "名前: 'レオン'
年齢:50
性別:20" 

rosservice listは、すべてのサービス名を一覧表示できます。

プログラムの結果は次のとおりです。

 

Pythonの検証は成功しました。

ソースコードはhttps://github.com/huchunxu/ros_21_tutorialsからダウンロードすることもできます

全文はここで紹介されています。
 

おすすめ

転載: blog.csdn.net/leon_zeng0/article/details/114994859