Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- gjk
- patch
- Turtlesim
- MPC
- remapping
- Service
- unittest
- Gradient
- roslaunch
- Python
- QT
- separating axis theorem(sat)
- narrow-phase
- broad-phase
- gjk-epa
- optimization
- Publish
- mock
- namespace
- convex
- subsribe
- CONSTRAINTS
- ROS
- Turtle
- Package
- UV
- rospy.spin
- 비동기적
- Topic
- 워크스페이스
Archives
- Today
- Total
똑바른 날개
ROS 공부 9일차 - C++로 노드를 생성해보다. 본문
위 코드는 ROS로 효과적인 로봇 프로그래밍하기 3판에 있는 코드와 설명을 사용하겠다.
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
ros::init(argc, argv, "example1_a");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<std_msgs::String>("message", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << " I am the example1_a node ";
msg.data = ss.str();
//ROS_INFO("%s", msg.data.c_str());
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
- ros::init(argc, argv, "example1_a") -> 노드를 초기화하고 이름을 정한다.
- ros::NodeHandle n -> 프로세스의 핸들러, 우리 코드가 환경과 상호작용할 수 있게 해준다.
- ros::Publisher pub = n.advertise<std_msgs::String>("message", 1000)
아래 코드는 발행자의 인스턴스를 만들고 마스터에 그 토픽의 이름과 타입을 알려준다.
토픽의 이름은 message이고, 두번째 파라미터는 버퍼의 크기이다. 만약 토픽이 데이터를 빨리 발행하면, 버퍼는 적어도 1000개의 메시지를 유지할 것이다.
버퍼란? 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 영역이다. 버퍼링(buffering)이란 버퍼를 활용하는 방식 또는 버퍼를 채우는 동작을 말한다.
- ros::Rate loop_rate(10) -> 데이터를 보내는 주파수를 정하는 것이다. 단위는 HZ이다.
- while(ros::ok()) -> Ctrl+C키가 눌러지거나 ROS가 모든 노드를 중지하면 노드를 정지시킨다.
- std_msgs::String msg; -> std_msg 의 string타입의 메세지를 msg로 선언
std::stringstream ss; -> std에서 string타입의 변수 ss 선언
ss << " I am the example1_a node "; -> ss안에 문자열을 집어넣는다.
msg.data = ss.str(); -> msg.data(string)에 ss의 문자열을 집어 넣는다. - pub.publish(msg); -> 변수msg에 담긴 정보를 pub 해준다.
- ros::spinOnce();
ros::spin | ros::spinOnce() | |
공통점 | 버퍼(큐)에 쌓여있는 콜백함수를 처리한다. | |
차이점 | 자체로 무한루프의 의미를 지니고 있다. 계속적으로 함수를 콜백한다. spin 다음에 있는 코드는 실행되지 않는다. |
호출 시점까지 버퍼에 쌓여있는 콜백함수를 처리한다. 그 후 다음 코드가 실행된다. |
- spin의 구현
while (ros::ok())
{
ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0.1));
}
- spinonce의 구현
ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0));
호출되는 순간 버퍼(큐)안에 쌓여있는 모든 콜백함수를 처리한 후 빠져나가고 다음 코드를 실행시킨다.
보통 spinonce는 위 코드와 같이 while문안에서 loop_rate.sleep()과 같이 사용된다.
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << " I am the example1_a node ";
msg.data = ss.str();
//ROS_INFO("%s", msg.data.c_str());
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
- loop_rate.sleep(); -> 코드를 설정한 주기적으로 돌리기 위해 사용되는 코드이다.
예시를 하나 들어보자. 주기가 4초로 설정된 코드에서 while문 안에서 코드가 실행되는 상황이다. ros::spinonce();까지 2초의 시간이 소요되었다. 그리고 loop_rate.sleep이 실행되면 2초동안 코드는 기다린 뒤에 다시 while문이 돌기 시작한다.
참고한 사이트
'ROS' 카테고리의 다른 글
ROS 공부 9일차 - rosnode, rostopic, rosservice, rosmsg, rosparam (0) | 2022.05.20 |
---|---|
ROS 공부 8일차 - python을 활용하여 센서 데이터 효율화 (0) | 2022.05.18 |
Ros 공부 7일차 - ros파일 시스템 이해, 여러가지 패키지 명령어 (0) | 2022.05.03 |
Ros 공부 6일차 - rosbag (0) | 2022.03.05 |
Ros 공부 4일차 - rospy.spin() (0) | 2022.03.03 |