코딩처음입니다만
군집 로봇, 모션 플래닝, 자율주행에 관심있는 SW 개발자입니다 !
코딩처음입니다만★/ROS (5)
[ROS] ROS subscriber 인자 넘기기 (pass argument on subscriber)
728x90
반응형

 

안녕하세요~ 오늘은 ROS Subscriber에서 매개변수로 파라미터를 넘기는 것을 해보겠습니다.

 

ROS subscriber 기본 코드

 

#include <ros/ros.h>
#include <my_msgs/TestString>
 
void msgCallback(const my_msgs::TestString::ConstPtr& msg)
{
  /*
   *
   *
   */
}
 
int main(int argc, char** argv)
{
  ros::init(argc, argv, "my_sub_node");
  ros::NodeHandle nh;
int id = 1419;
 
  ros::Subscriber sub_time = nh.subscribe("topic", 1, msgCallback);
 
  ros::spin();
 
  return 0;
}

ROS를 어느정도 접하신 분이라면 이 정도의 코드는 이해하실 거라 믿습니다.

"topic"이라는 이름의 토픽을 subscribe하며 queue 사이즈는 1

그리고 무한루프를 돌면서 호출된 msgCallback함수를 동작시킵니다.

 

===============================================================

 

 

만약 여기서 int id = 1419;

id를 콜백함수의 매개변수로 넣기 위해서는 어떻게 해야 할까요?

 

바로 boost 라이브러리의 bind함수를 이용하면 됩니다.

 

Boost 라이브러리를 이용한 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
#include <ros/ros.h>
#include <boost/bind.hpp>
#include <my_msgs/TestString>
 
void msgCallback(const my_msgs::TestString::ConstPtr& msg, int id)
{
  /*
   *
   *
   */
}
 
int main(int argc, char** argv)
{
  ros::init(argc, argv, "my_sub_node");
  ros::NodeHandle nh;
  int id = 1419;
 
  ros::Subscriber sub_time = nh.subscribe<my_msgs::TestString>("topic"1, boost::bind(&msgCallback, _1, id));
  ros::spin();
 
  return 0;
}
cs

#include <ros/ros.h>

#include <my_msgs/TestString>

 

void msgCallback(const my_msgs::TestString::ConstPtr& msg)

{

  /*

   *

   *

   */

}

 

int main(int argc, char** argv)

{

  ros::init(argc, argv, "my_sub_node");

  ros::NodeHandle nh;
int id = 1419;

 

  ros::Subscriber sub_time = nh.subscribe("topic"1, msgCallback);

 

  ros::spin();

 

  return 0;

}

// 코드 설명

#include <boost/bind.hpp>

를 통해 boost라이브러리를 include 해줍니다

 

기존 코드와 달라진 점이 있다면

nh.subscribe<메세지타입>("토픽이름", 큐사이즈, boost::bind(&msgCallback, _1, 파라미터1));

이 부분이 아닐까 싶습니다.

 

1. 메세지 타입을 정의할 것

2. subscribe함수의 3번째 인자에는 boost::bind()를 넣을 것

3. boost::bind()의 첫 번 째 인자 -> 콜백함수의 주소를 참조로 넘겨줄 것

4. placeholder 은 뒤의 파라미터의 개수에 상관없이 무조건 _1 을 넣을 것

 

 

================================================================================

 

잠깐, 여기서 boost라이브러리를 못 찾을 때 

CMakeLists.txt에서 아래 두 줄을 추가해줍니다.

 

 

반응형
  Comments,     Trackbacks
[ROS/PCL] PointCloud2 샘플데이터 재생 rosbag
728x90
반응형

How to visualize PointCloud2 on rviz

How to play bag file using rosbag

 

 

 

[블로그 이전 관련!!]

더나은 환경에서 양질의 게시글을 제공하기 위해 블로그를 옮겼습니다

아래쪽 주소로 들어가지면 PointCloud2 샘플 데이터 재생하는 것을 정리해놓았습니다!

https://bigbigpark.github.io/ros/ros-pointcloud2-rosbag/

 

 

 

 

 

 

안녕하세요~ 오늘은 rosbag파일을 재생하면서 rviz에 시각화해보겠습니다!

재생할 bag 파일은 ouster사에서 제공하는 sample data이구요!

 

URL : ouster.com

 

High-resolution digital lidar: autonomous vehicles, robotics, drones

Lidar sensors for high-resolution, long range use in autonomous vehicles, robotics, mapping. Low-cost & reliable for any use case.

ouster.com

 

여기서 다운로드 하실 수 있습니다

 

 

전체적인 컨셉

 

- roscore 실행

- rosbag 실행

- rviz 실행 후 visualization

이 순서로 진행해보겠습니다! 차근차근 따라오시면 됩니다 ㅎㅎ

 

 

$roscore

 

 

 

 

$rosbag play OS1-64_city3.bag -l

 

bag파일을 재생하기 위한 명령어입니다.

$rosbag play [bag파일 이름]

순서로 입력해주시면 되고 끝에 -l무한반복하겠다는 옵션입니다

 

 

$rostopic list

 

rostopic list 를 이용하여 현재 publish/subscribe 중인 토픽 명을 모두 확인할 수 있습니다

 

 

$rosbag info OS1-64_city3.bag

 

 

rosbag info를 통해 bag파일의 정보를 얻을 수 있습니다

간단하게 보시면 파일 경로, duration, size, 토픽들 등을 확인할 수 있습니다.

이 때 저희는 /os1_cloud_node/points  ...   sensor_msgs/PointCloud2에 집중할게요!

 

 

$rviz

 

 

rviz를 실행하셔서 토픽 중 PointCloud2를 선택해주세요!

 

토픽명 설정 -> /os1_cloud_node/points

 

 

이제 global frame_id만 기입하면 되는데 rosbag info에서는 그 정보가 없었습니다.

따라서 rostopic echo를 이용하여 frame_id를 알아내봅시다!

 

 

$rostopic echo /os1_cloud_node/points | grep frame_id

 

 

rostopic echo /os1_cloud_node/points | grep frame_id

 

위의 명령어는 | (리눅스에서는 AND 동작)로 구성이 되어있습니다.

따라서 rostopic echo를 하는데 frame_id라고 출력되는 부분을 grep(잡다)하는 명령어 입니다.

출력 결과물을 보시면 frame_id: "/os1_lidar"라고 출력되는 것을 볼 수 있습니다.

 

따라서 이를 rviz의 global frame에 입력해주시면 pointcloud2 bag파일을 성공적으로 재생할 수 있습니다~

 

 

결과(output)

 

 

 

전체 실행 동영상

 

 

반응형
  Comments,     Trackbacks
[PointCloud] PCL 라이브러리 설치하기! install pcl on ubuntu 18.04
728x90
반응형

안녕하세요~ 오늘은 PCL 라이브러리 설치에 대해 알아보겠습니다!

설치 환경 : Ubuntu 18.04

 

$sudo apt install libpcl-dev

 

- 터미널 창에서 입력해주시면 다운로드가 완료됩니다!

- Just type that command on your terminal

 

반응형
  Comments,     Trackbacks
[ROS] 간단한 publisher와 subscriber (topic tutorial)
728x90
반응형

 

[블로그 이전 관련!!]

더나은 환경에서 양질의 게시글을 제공하기 위해 블로그를 옮겼습니다

아래쪽 주소로 들어가지면 게시글을 새로 정리해놓았습니다!

https://bigbigpark.github.io/ros/rospy-tutorial/

 

 

 

 

 

 

 

안녕하세요~ 오늘은 ros tutorial 중 기본 중의 기본인

ros publisher와 ros subscriber을 작성해보겠습니다!

또한 custom 메세지를 빌드하고 추가하는 방법도 알아보겠습니다

 

 

전체 코드는 본문 제일 하단에 첨부하겠습니다

 

 

전체적인 컨셉

 

- catkin_create_pkg를 이용하여 프로젝트 빌드

- publisher와 subscriber를 하나씩 작성

- TestMsg.msg라는 메세지 파일을 생성하고 헤더파일로 불러오기

 

 

$catkin_create_pkg tistory_tutorial roscpp std_msgs message_generation

 

 

// 설명

- tistory_tutorial 프로젝트에 roscpp, std_msgs, message_generation이라는 종속 패키지를 추가하겠다

 

 

$touch msg_pub.cpp msg_sub.cpp [경로 주의]

 

 

{프로젝트 경로}/src에서

msg_pub.cpp

msg_sub.cpp

라는 두 개의 cpp파일 생성

 

 

msg_pub.cpp , msg_sub.cpp 코드 스켈레톤 작성

 

- 스켈레톤이 해골 뼈다구잖아요?

- 그래서 코드 스켈레톤(=code skeleton)하면 코드 뼈대랑 같은 말입니다

 

msg_pub.cpp
msg_sub.cpp

 

★ 메세지 정의 ★

 

 

// 프로젝트 안에 msg폴더를 생성하고 그 안에 TestMsg.msg를 생성하는 과정입니다 

$roscd tistory_tutorial
$mkdir msg
$cd msg
$gedit TestMsg.msg

 

메세지 폴더 안에서는

float64 x

float64 y

float64 z

해서 저장(Ctrl+S) 해주세요!!

 

 

package.xml 수정

 

 

57번과 60번 줄을 추가해주세요!

 

 

CMakeLists.txt 수정

 

 

위의 사진과 같이 추가해주시면 됩니다~!

간단하게 설명하자면 

add_message_files는 프로젝트 안 'msg'폴더 안에 있는 메세지 파일을 생성하겠다는 뜻이에요

generate_messages는 추가된 메세지나 서비스에 밑에 나열된 종속패키지를 추가한다는 말입니다

 

 

$catkin_make

 

 

catkin_make로 빌드를 해줍니다

이 경우 TestMsg.msg 파일이 TestMsgs.h파일로 알아서 만들어집니다 ㅎㅎ

따라서 저희가 할 거는 cpp파일에서 헤더파일을 include 하는 작업만 남아있습니다!

 

 

cpp파일에서 헤더파일 추가

 

 

#include <프로젝트_이름/메세지_이름.h>

순으로 선언해주시면 됩니다

이제 본격적인 publishersubscriber를 만들어봅시다!!

 

 

msg_pub.cpp

 

 

주석 단다고 달았는데

질문 있으시면 댓글 남겨주세요~ ㅎㅎ

밑에 subscribe도 첨부했습니다

 

 

msg_sub.cpp

 

 

자 이제 모든 준비가 끝났습니다

msg_pub.cpp와 msg_sub.cpp파일 작성이 끝났으니

이제 실행가능한 형태(=노드)로 설정해주는 작업만 남았네요

 

 

CMakeLists.txt에서 파일 실행가능하도록 변경

 

 

- CMakeLists.txt 에서 아래쪽으로 좀 스크롤을 내려보시면 이와 비슷한 코드가 주석처리가 되어 있는데

아무데나 이렇게 넣어주시면 됩니다!

 

간단하게 설명을 드리자면,

add_executable(msg_pub src/msg_pub.cpp)

add_executable(실행할 때 사용할 노드명 src/실제 코드) 입니다

 

add_dependencies(msg_pub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(msg_pub ${catkin_LIBRARIES})

비슷하게 위의 두 명령어 제일 앞부분에 실행할 때 사용할 노드명(ex. msg_pub) 을 적어주시면 됩니다

 

마지막으로 catkin_make를 해줄게요~!

 

 

 

결과

 

 

 

 

전체 코드

msg_pub.cpp

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
#include <ros/ros.h>
#include <tistory_tutorial/TestMsg.h>
 
int main(int argc, char** argv)
{
    // ros node 초기화
    ros::init(argc, argv, "msg_pub_node");
    ros::NodeHandle nh;
 
    // loop_rate를 1 Hz로 설정 
    ros::Rate r(1);
 
    // "chat"이라는 이름의 토픽을 publish 하고, 큐(queue)의 크기는 1로 설정
    ros::Publisher pub = nh.advertise<tistory_tutorial::TestMsg>("chat"1);
    tistory_tutorial::TestMsg msg;
 
    while(ros::ok())
    {
        msg.x = 10;
        msg.y = 100;
        msg.z = 1000;
 
        pub.publish(msg);
        r.sleep();
    }
 
    return 0;
}
cs

 

msg_sub.cpp

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
 
#include <ros/ros.h>
#include <tistory_tutorial/TestMsg.h>
 
void msgcallBack(const tistory_tutorial::TestMsg::ConstPtr& msg)
{
    ROS_INFO("x : %f", msg->x);
    ROS_INFO("y : %f", msg->y);
    ROS_INFO("z : %f", msg->z);
}
 
int main(int argc, char** argv)
{
    // ros node 초기화
    ros::init(argc, argv, "msg_sub_node");
    ros::NodeHandle nh;
 
    // loop_rate를 1 Hz = 1초로 설정
    ros::Rate r(1);
 
    // "chat"이라는 이름의 토픽을 publish 하고, 큐(queue)의 크기는 1로 설정
    ros::Subscriber sub = nh.subscribe<tistory_tutorial::TestMsg>("chat"1, msgcallBack);
    tistory_tutorial::TestMsg msg;
 
    while(ros::ok())
    {
        ros::spinOnce();
        
        r.sleep();
    }
 
    return 0;
}
 
 
cs

 

반응형
  Comments,     Trackbacks
[ROS] ros::spin, ros::spinOnce 차이점
728x90
반응형

[블로그 이전 관련!!]

더나은 환경에서 양질의 게시글을 제공하기 위해 블로그를 옮겼습니다

아래쪽 주소로 들어가지면 을 새로 정리해놓았습니다!

https://bigbigpark.github.io/ros/ros-spin/

 

 

 

 

 

 

 

 

안녕하세요~ 뉴기니아입니다!

오늘은 ros::spin이랑 ros::spinOnce의 차이점에 대해서 알아보겠습니다!

 

ros에서는 msg가 토픽으로 수신되면 그것을 큐(queue)에 쌓습니다.

그 후 subscribe쪽에서 spin() 메소드를 이용해서 큐에 있는 메세지를 처리하도록 구성되어있는데요.

spin, spinOnce 모두 Subscribe 할 때 해당 callBack함수를 실행시키는 역할을 합니다.

 

What is difference?

 

 

 

ros::spin()

 

쉽게 말해 ros::spin() 은 일종의 무한루프라고 보시면 됩니다.

즉, 리턴값이 없이 이전까지 처리된 callBack 함수를 기억해서 계~속 반복한다고 생각하시면 되구요

이 경우 별도의 while문을 사용하지 않아도 됩니다.

터미널 창에서 Ctrl+C 이나 ros main 프로세스가 종료될 때까지는 계속 실행됩니다.

이 때 spin 이후의 코드는 실행되지 않으니 주의해주세요

 

 

 

ros::spinOnce()

 

ros::spin()에 비해서 정말 유연하고 자주 사용되는 방법입니다.

ros::spinOnce()는 이름에서도 느껴지듯 한번 돈다? 이런 뉘앙스가 풍깁니다

이는 현재까지 요청된 모든 callBack함수를 모두 호출하고 코드 다음 줄로 넘어갑니다.

이 경우 필요한 게 while(ros::ok())loop_rate.sleep()를 필요로 합니다

 

※ loop_rate.sleep()는 ros::Rate() 메소드를 이용하여 정의합니다

 

특히 특정 센서 데이터나 현재 상태를 정해진 주기(ex. 100 Hz)로 업데이트 시켜야할 때 좋겠죠?

 

 

ros::spin() 사용예제
1
2
3
4
5
6
7
8
9
int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
 
    ros::Subscriber sub = n.subscribe("chat"1, chatcallback);
 
    ros::spin();
    return 0;
}
cs

 

 

 

ros::spinOnce() 사용 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
 
    ros::Subscriber sub = n.subscribe("chat"2, chatcallback);
 
    ros::Rate loop_rate(10);
    while (ros::ok())
    {
        /*...TODO...*/ 
 
        ros::spinOnce();
 
        loop_rate.sleep();
    }
    return 0;
}
cs

 

 

반응형
  Comments,     Trackbacks