ROS 기본 프로그래밍
목차
- ROS 프로그래밍 전에 알아둬야 할 사항
- 퍼블리셔와 서브스크라이버 노드 작성 및 실행
- 서비스 서버와 클라이언트 노드 작성 및 실행
- 액션 서버와 클라이언트 노드 작성 및 실행 -> 잘 사용하지 않아서 강의 X
- 파라미터 사용법
- Roslaunch 사용법
1. ROS 프로그래밍 전에 알아둬야할 사항
- 표준 단위 : SI 단위 사용
- 좌표 표현 방식
- x : forward / y : left / z : up
-> 정회전 : left -> (+) / 역회전 : right -> (-)
- 오른손 법칙
- 프로그래밍 법칙
2. 메시지 통신의 종류
- topic
- 퍼블리셔가 서브스크라이버에게 메시지를 전달하는 방식
- 서비스
- 서비스 클라이언트가 서비스 서버에 서비스를 요청하면 서비스 응답을 받는 방식
- 양방향 일회성
- 매개변수
- roscore 실행하면 ros master의 역할
- ros log를 저장
- 파라미터 서버를 구동
- 사용자가 입력한 파라미터를 저장
- 토픽 작성
1) 패키지 생성
- $cd ~/catkin_ws/src
- ~의 역할 : 홈 폴더
ex) 전체 리눅스 폴더 > home > user의 폴더
- catkin_ws : catkin workspace
2) catkin_create_pkg ros_tutorials_topic message_generation std_msg roscpp
- 자동적으로 패키지 생성
- include 폴더 (만든 당시에는 빈 폴더) + src 폴더 (소스코드 파일)
- CMakeLists.txt / package.xml -> 가장 기본적인 폴더 생성
- 명령어 실행 시
- create_pkg : 패키지 생성
- ros_tutorials_topic : 패키지 이름
- message_generation std_msg roscpp : 세가지 패키지를 사용한다는 의미
3) cd ros_tutorials_topic
- 데릭토리 변경
4) ls
- list를 의미
- 생성 파일 보기
5) 패키지 설정 파일(pakage.xml) 수정
- ros의 필수 설정 파일 중 하나인 pakage.xml은 패키지 정보를 담은 XML 파일로서 패키지 이름, 저작자, 라이선스, 의존성 패키지 등을 기술
- gedit package.xml
- editor 화면 / 기본 메모장
<?xml version="1.0"?>
- 특정 버전 이상에서 사용 가능하다는 것을 암시
<package>
- 패키지 태그 // 시작
<name>ros_tutorials_topic</name>
- 패키지 이름 넣기
<version>0.1.0</version>
- 버전 태그
<description>ROS turtorial package to learn the topic</description>
- 패키지의 간략한 설명 넣어주기 / 검색키로도 사용 / 위키페이지로 연결
<license>Apache 2.0</license>
- 개발할때 적용되는 라이센스
<author email="pyo@robotis.com">Yoonseok Pyo</author>
- 저자 메일 적어주기
<maintainer email="pyo@robotis.com">Yoonseok Pyo</maintainer>
- 초반에는 저자(개발자)와 메인터너와 동일 / 후반에는 달라질 수 있음
<url type="website">http://www.robotis.com</url>
<url type="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
<url type="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url >
<buildtool_depend>catkin</buildtool_depend> - 의존성 관계 설명 / 현재는 catkin
<build_depend>roscpp</build_depend>
- 빌드 시 의존성 / C++ 사용
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
- 메시지 만들기
<run_depend>roscpp</run_depend>
- 실행 시 의존성
<run_depend>std_msgs</run_depend>
<run_depend>message_runtime</run_depend>
<export></export >
</package>
6) 빌드 설정 파일(CMakeLists.txt)
- 노드 빌드 시 사용되는 옵션의 집합
cmake_minimum_required(VERSION 2.8.3)
- 2.8.3 버전 이상이면 사용 시 문제 없음을 의미
project(ros_tutorials_topic)
find_package(catkin REQUIRED COMPONENTS message_generation std_msgs roscpp)
- 캐킨 빌드를 할 때 요구되는 구성요소 패키지
- 의존성 패키지로 message_generation, std_msgs, roscpp이며 이 패키지들이 존재하지 않으면 빌드 도중에 에러 발생
add_message_files(FILES MsgTutorial.msg)
- 메시지 선언 : MsgTutorial.msg
generate_messages(DEPENDENCIES std_msgs)
- 의존하는 메시지를 설정하는 옵션
-std_msgs가 설치되어 있지 않다면 빌드 도중에 에러 발생
catkin_package(
LIBRARIES ros_tutorials_topic - 패키지 이름
CATKIN_DEPENDS std_msgs roscpp - 의존성 기술
)
- 캐킨 패키지 옵션으로 라이브러리, 캐킨 빌드 의존성, 시스템 의존 패키지를 기술
include_directories(${catkin_INCLUDE_DIRS}) - include 헤더 파일 추가 할 땐 뒤에 include를 적어주면 됨
- 인클루드 디렉터리 설정
add_executable(topic_publisher src/topic_publisher.cpp) - 실행파일에 대한 정보 기술 / 생성 노드 : topic_publisher / 참고 : src/topic_publisher.cpp
add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - 퍼블리셔 노드를 만들 때 참조할 내용
target_link_libraries(topic_publisher ${catkin_LIBRARIES}) -
- topic_publisher 노드에 대한 빌드 옵션
- 실행 파일, 타깃 링크 라이브러리, 추가 의존성 등을 설정
add_executable(topic_subscriber src/topic_subscriber.cpp) - 생성노드 : topic_subscriber / 참고 : src/topic_subscriber.cpp
add_dependencies(topic_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
target_link_libraries(topic_subscriber ${catkin_LIBRARIES})
- topic_subscriber 노드에 대한 빌드 옵션
7) 메시지 파일 작성
- 디렉토리 변경 후 msg 메시지 폴더 생성
- msg 폴더로 디렉토리 변경후 파인 신규 작성 및 내용 수정
- ex) 입력한 메시지 데이터
- time stamp / int32 data
- 메시지 형식 + 메시지 이름
- 메시지 타입은 위 두개를 포함한 bool, int8, int16, float32, string, time, duration 등의 메시지 기본 타입을 사용 가능
- ROS에서 많이 사용되는 메시지를 모아놓은 common_msgs 등이 있음
8) 퍼블리셔 노드 작성
- 실행파일은 devel과 build에 들어가있음 // 실제로는 안들어가 있었다. gpt한테 물어봤는데 걔는 이게 잘 빌드가 되었다고 한다. 무언가 잘못되었다. 이상하다.
- 코드
#include "ros/ros.h" // ROS 기본 헤더파일
#include "ros_tutorials_topic/MsgTutorial.h" // MsgTutorial 메시지 파일 헤더(빌드 후 자동 생성)
int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc, argv, "topic_publisher"); // 노드명 초기화
ros::NodeHandle nh; // ROS 시스템과 통신을 위한 노드 핸들 선언
ros::Publisher ros_tutorial_pub = nh.advertise<ros_tutorials_topic::MsgTutorial>("ros_tutorial_msg", 100);
// 퍼블리셔 선언, ros_tutorials_topic 패키지의 MsgTutorial 메시지 파일을 이용
// 퍼블리셔 ros_tutorial_pub 를 작성
// 토픽명은 "ros_tutorial_msg"
// 퍼블리셔 큐사이즈를 100개로 설정
ros::Rate loop_rate(10);
// 루프 주기를 설정
// 10Hz / 0.1초 간격으로 반복
ros_tutorials_topic::MsgTutorial msg;
// MsgTutorial 메시지 파일 형식으로 msg 라는 메시지를 선언
int count = 0;
// 메시지에 사용될 변수 선언
while (ros::ok())
{
msg.stamp = ros::Time::now(); // 현재 시간을 msg의 하위 stamp 메시지에 기록
msg.data = count; // count변수 값을 msg의 하위 data 메시지에 기록
ROS_INFO("send msg = %d", msg.stamp.sec); // stamp.sec 메시지를 표시
ROS_INFO("send msg = %d", msg.stamp.nsec); // stamp.nsec 메시지를 표시
ROS_INFO("send msg = %d", msg.data); // data 메시지를 표시
// ROS_INFO는 printf와 동일한 역할
ros_tutorial_pub.publish(msg); // 메시지를 발행
loop_rate.sleep(); // 위에서 정한 루프 주기에 따라 슬립에 들어감
++count; // count 변수 1씩 증가
}
return 0;
}
9) 서브스크라이버노드
#include "ros/ros.h" // ROS 기본 헤더파일
#include "ros_tutorials_topic/MsgTutorial.h"
// MsgTutorial 메시지 파일 헤더 (빌드 후 자동 생성됨)
// 메시지 콜백 함수로써, 밑에서 설정한 ros_tutorial_msg라는 이름의 토픽
// 메시지를 수신하였을 때 동작하는 함수
// 입력 메시지로는 ros_tutorials_topic 패키지의 MsgTutorial 메시지를 수신
void msgCallback(const ros_tutorials_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recieve msg = %d", msg->stamp.sec); // stamp.sec 메시지를 표시
ROS_INFO("recieve msg = %d", msg->stamp.nsec); // stamp.nsec 메시지를 표시
ROS_INFO("recieve msg = %d", msg->data); // data 메시지를 표시
}
int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc, argv, "topic_subscriber"); // 노드명 초기화
ros::NodeHandle nh; // ROS 시스템과 통신을 위한 노드 핸들 선언
// 서브스크라이버 선언, ros_tutorials_topic 패키지의 MsgTutorial 메시지 파일을 이용
// 서브스크라이버 ros_tutorial_sub 를 작성
// 토픽명은 "ros_tutorial_msg" 이며,
// 서브스크라이버 큐사이즈를 100개로 설정
ros::Subscriber ros_tutorial_sub = nh.subscribe("ros_tutorial_msg", 100, msgCallback);
// 콜백함수 호출을 위한 함수
// 메시지가 수신을 대기
// 수신되었을 경우 콜백함수를 실행
ros::spin();
return 0;
}
- 노드 하나당 퍼브스크라이버 한번, 서브스크라이버 한번의 역할을 하는 것은 아님
- 복수의 역할을 할 수 있음
10) 퍼블리셔 실행
- 무언가 잘못되어 결과를 눈으로 보지 못했다.
- cd ~/catkin_ws/src에 분명히 ros_tutorials_topic 파일이 있지만 터미널에서 없다고 나온다.
- 서비스 작성
- 요청이 있을 때만 응답하는 서비스 서버
1) 패키지 생성
- 토픽-2) 와 동일 방식
2) 패키지 설정 파일 수정
- 토픽-5) 와 동일 방식
3) 빌드 설정 파일 작성
- 토픽-6) 과 동일 방식
4) 서비스 파일 작성
- 토픽-7) 과 동일 방식
- 차이점 : ---을 사용하여 요청과 응답을 구분하는 구분자
5) 서비스 서버 노드 작성
- 코드
- 토픽-8과 유사하므로 생략
6) 서비스 클라이언트 노드 작성
- 코드
-토픽-9와 유사하므로 생략
7) ROS 노드 빌드
- 예제를 따라했지만 계속 같은 문제로 실패했다.
- rqt그래프는 사용이 불가능
- 서비스 클라이언트 역할은 노드를 써서 만들 필요는 없다.
- 명령어를 통하여 역할 대체 가능
- rqt를 사용하여 역할 대체 가능
- service caller 설정
- 해당 srv 폴더로 이동
- 값 선택 후 call
- 파라미터 작성
1) 파라미터를 활용한 노드 작성
- 서비스 서버와 클라이언트 노드에서 service.cpp 소스를 수정하여 사용
- #define을 통하여 코드 수정
- 차이점 :
- nh.setParam("calculation_method", PLUS); // 매개변수 초기설정
- nh.getParam("calculation_method", g_operator); // 무조건 대기상태에서 중간중간 확인을 위해 루프 설정
2) 노드 빌드 및 실행
3) 매개변수 목록 보기
- roslaunch
- rosrun은 하나의 노드를 실행하는 명령을 하는 명령어
- roslaunch는 하나 이상의 정해진 노드를 실행시킴
- 패키지의 매개변수나 노드이름변경, 노드 네임스페이스 설정, ROS_ROOT 및 ROS_PACKAGE_PATH설정, 환경 변수 변경 등의 옵션을 붙일 수 있는 ROS 명령어
- XML 기반
- 사용법
1) roslaunch의 활용
- 디렉토리 변경
- mkdir 통해 폴더 생성
- 내용 기입
- 실행
- info, error등 표시가 되지 않아 --screen을 사용하여 출력
- 두개의 노드를 실행하면 터미널에는 두개 다 표시되고 하나의 메시지를 두개의 서브스크라이버가 각각 받게됨
- 개별적으로 받게하고싶으면 그룹을 넣어 실행 -> 분리적으로 서비스 전달
- 노드의 이름이 변경됨
2) launch 태그
<launch> - roslaunch 구문의 시작과 끝을 가리킴
<node> - 노드 실행에 대한 태그 / 패키지, 노드명, 실행명을 변경 가능
<machine> - 노드를 실행하는 PC의 이름, address, ros-root, ros-package-path 등을 설정
<include> - 다른 패키지나 같은 패키지에 속해 있는 다른 launch를 불러와 하나의 launch파일처럼 실행
<remap> - 노드 이름, 토픽 이름 등의 노드에서 사용 중인 ROS 변수의 이름을 변경
<env> - 경로, IP 등의 환경 변수를 설정 / 거의 안 쓰임
<param> - 매개변수 이름, 타이프, 값 등을 설정
<rosparam> - rosparam 명령어 처럼 load, dump, delete 등 매개변수 정보의 확인 및 수정
<group> - 실행되는 노드를 그룹화할 때 사용
<test> - 노드를 테스트할 때 사용
'FOSCAR-(Autonomous Driving) > ROS 스터디' 카테고리의 다른 글
[2025 ROS 스터디] 이승찬 #3주차 - ROS 기본 프로그래밍 (0) | 2025.01.31 |
---|---|
[2025 ROS 스터디] 홍동형 #3주차-ROS 기본 프로그래밍 (0) | 2025.01.31 |
[2025 ROS 스터디] 신채영 #2주차 - ROS 용어, 도구 (0) | 2025.01.23 |
[2025 ROS 스터디] 이영상 #2주차- ROS 용어, 명령어, 도구 (0) | 2025.01.22 |
[2025 ROS 스터디] 이동규 #2주차 - ROS와 한걸음 더 친해지기 (1) | 2025.01.22 |