본문 바로가기
IT 프로그래밍 관련/ROS

ROS 패키지 생성하기(한 노드에 여러기능 )

by 지나는행인 2021. 6. 17.
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

위의 노드는 서브크라이버와 서버클라이언트 역할을 하는 노드이다.

 

잘 보고 파악해보자...

 

퍼블리셔를 계속 하고있고 , 조건에 따라 서브크라이버에서 요청을 주면 , 서버에서 받아 , 더하기를 해서 ,

 

클라이언트로 응답한다.

 

댓글