728x90
아래에서 하나의 노드에 퍼블리셔나 서브크라이버 .
하나씩만 기능을 주었었다.
하지만 , 하나의 노드에 여러개의 기능을 넣어서 작성하는 것이 가능하고 , 또한 대부분 그렇게 패키지가 구성되어 있다.
먼저 , 토픽이나 서비스를 이용할 시 디렉토리를 msg 나 ,srv디렉토리를 만들어주었는데 !
두가지의 기능을 이용하려면 , 두 개의 디렉토리를 다 만들어서 각 디렉토리에 메시지 파일을 만들어 주어 사용한다.
위와 같은 식으로 디렉토리를 만들고 ,
src에 기존대로 노드 파일을 만든다.
이번에 만든 것은 두개의 노드로,
하나는 퍼블리셔와 서비스 서버의 기능을 하는 노드, 하나는 서브스크라이버와 서버스 클라이언트 기능을 하는 노드이다.
아래는 노드를 작성한 코드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include "ros/ros.h"
#include "yh_topic_service/yh_msg_210611.h"
#include "yh_topic_service/yh_srv_210611.h"
bool calculation(yh_topic_service::yh_srv_210611::Request &req, yh_topic_service::yh_srv_210611::Response &res) // 서비스 요청을 받아서 실행
{
res.result = req.a + req.b;
ROS_INFO("request : x = %d, y = %d",(int)req.a,(int)req.b);
ROS_INFO("sending back response : %d",(int)res.result);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "yh_pub_server");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<yh_topic_service::yh_msg_210611>("yh_pub_srv_210611",100);
ros::ServiceServer server = nh.advertiseService("yh_sub_client_210611", calculation);
ros::Rate loop_rate(10);
yh_topic_service::yh_msg_210611 msg;
int count = 0;
int count_ms = 0;
while(ros::ok())
{
msg.stamp = ros::Time::now();
msg.data = count_ms;
ROS_INFO("send msg = %d", msg.stamp.sec);
ROS_INFO("send msg = %d", msg.data);
if(count_ms % 10 == 0)
{
msg.data1 = count;
ROS_INFO("send msg = %d", msg.data1);
count = count+3;
}
pub.publish(msg);
loop_rate.sleep();
count_ms++;
ros::spinOnce();
}
return 0;
}
|
위 노드는 퍼블리셔와 서버 기능을 하는 노드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#include "ros/ros.h"
#include "yh_topic_service/yh_msg_210611.h"
#include "yh_topic_service/yh_srv_210611.h"
void msgCallback(const yh_topic_service::yh_msg_210611::ConstPtr&msg) //const 상수
{
if(msg -> data % 100 == 0)
{
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<yh_topic_service::yh_srv_210611>("yh_sub_client_210611");
yh_topic_service::yh_srv_210611 srv;
srv.request.a = msg -> data;
srv.request.b = msg -> data1;
if(client.call(srv))
{
ROS_INFO("send srv, Request.a and b : %d, %d",(int)srv.request.a, (int)srv.request.b);
ROS_INFO("receiving srv, Response.result : %d",(int)srv.response.result);
}
else
{
ROS_ERROR("Failed to call service");
}
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "yh_sub_client");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("yh_pub_srv_210611",100,msgCallback);
ros::spin(); //어떤 값이 들어오기 전까지 대기 (다시 위로 올라감)
return 0;
}
|
cs |
위의 노드는 서브크라이버와 서버클라이언트 역할을 하는 노드이다.
잘 보고 파악해보자...
퍼블리셔를 계속 하고있고 , 조건에 따라 서브크라이버에서 요청을 주면 , 서버에서 받아 , 더하기를 해서 ,
클라이언트로 응답한다.
'IT 프로그래밍 관련 > ROS' 카테고리의 다른 글
ROS launch 파일 만들기 (0) | 2021.06.11 |
---|---|
ROS 분석하는 방법(자주 쓰이는 분석 명령어...) (0) | 2021.06.11 |
ROS 패키지 생성하기(ServiceServer, ServiceClient, Service사용) (0) | 2021.06.09 |
ROS 패키지 생성하기(Publisher, Subscriber, Topic사용) (0) | 2021.06.08 |
ROS 패키지 디렉토리 (0) | 2021.06.08 |
댓글