[ROS] ROS프로그래밍 기초

강형우·2022년 11월 20일
0

ROS

목록 보기
4/5

1. ROS Package 기초

  • ROS 패키지

  • Package
    ROS에서 개발되는 소프트웨어를 논리적 묶음으로 만든 것
  • $ rospack list
    어떤 패키지들이 있는지 나열
  • rospack find [package_name]
    이름을 이용해서 패키지 검색
  • roscd [location_name[/subdir]]
    ROS 패키지 디렉토리로 이동
  • rosls [location_name[/subdir]]
    Linux ls와 유사(경로를 몰라도 이름 적용 가능)
  • rosed [file_name]
    (환경설정에 따른) 에디터로 파일을 편집

2. ROS Package 만들기

  • package 담을 디렉토리로 이동
    $ cd ~/xycar_ws/src
  • package 새로 만들기
    $ catkin_create_pkg [패키지이름] [패키지가 의존하고 있는 다른 패키지들 나열]
    $ catkin_create_pkg my_pkg1 std_msgs rospy
  • 예시
    package 이름은 my_pkg1, package가 의존하고 있는 다른 패키지들은 std_msgs, rospy 2개 이다.
  • 새로 만든 패키지를 빌드
    $ cd ~/xycar_ws
    $ catkin_make
    -> $ cm 명령어로 한번에 실행할 수 있다.
    ~/.bashrc 파일에서 아래와같이 alias선언을 했기 때문에
    alias cm = ' cd ~/xycar_ws && catkin_make'
  • 만들어진 패키지 확인
    $ rospack find my_pkg1
    패키지의 위치를 찾아준다
    $ rospack depends1 my_pkg1
    my_pkg1에서 의존하고 있는 다른 패키지들을 보여준다(rospy, std_msgs)
    $ roscd my_pkg1
    my_pkg1위치로 이동시켜준다

예시) ~/xycar_ws/src/my_pkg1/src에 pub.py 작성

#!/usr/bin/env python
  
import rospy
from geometry_msgs.msg import Twist

rospy.init_node('my_node', anonymous=True) #노드를 만들어준다(my_node)
pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10) #Publisher객체를 생성한다.

msg = Twist()
msg.linear.x = 2.0
msg.linear.y = 0.0
msg.linear.z = 0.0
msg.angular.x = 0.0
msg.angular.y = 0.0
msg.angular.z = 1.8

rate = rospy.Rate(1)

while not rospy.is_shutdown():
    pub.publish(msg)
    rate.sleep()

예시) ~/xycar_ws/src/my_pkg1/src에 pub.cpp 작성

#include "ros/ros.h"
#include "geometry_msgs/Twist.h"

int main(int argc, char** argv)
{
	ros::init(argc, argv, "my_node", ros::init_options::AnoymousName);
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
    
    geometry_msgs::Twist msg;
    msg.linear.x = 2.0
	msg.linear.y = 0.0
	msg.linear.z = 0.0
	msg.angular.x = 0.0
	msg.angular.y = 0.0
	msg.angular.z = 1.8
    
    ros::Rate rate(1);
    
    while(ros::ok())
    {
    	pub.publish(msg);
        msg.angular.z *= -1;
        rate.sleep();
    }
    
    return 0;
}

예시) ~/xycar_ws/src/my_pkg1/src에 sub.py 작성

#!/usr/bin/env python
  
import rospy
from turtlesim.msg import Pose

def callback(data):
    s = "Location: %.2f, %.2f" % (data.x, data.y)
    rospy.loginfo(rospy.get_caller_id() + s)

rospy.init_node("my_listener", anonymous=True) #노드를 만들어준다(my_listener)
rospy.Subscriber("/turtle1/pose", Pose, callback) #subscriber 객체 생성, 메세지를 수신하면 callback함수가 호출됨
rospy.spin()

프로그램 실행 권한

  • 작성한 파이썬 코드를 실행시키기 위해선 실행권한이 있어야 한다.
  • 다음과 같은 방법으로 실행권한을 부여한다.
    $ chmod +x pub.py
  • $ ls -l 명령으로 실행권한 여부를 확인할 수 있다.

3. ROS 프로그램의 실행과 검증 확인

프로그램 실행 방법

  • terminal#1에서 $ roscore
  • terminal#2에서 $ rosrun turtlesim turtlesim_node
  • 조금 전 만든 pub.py 프로그램을 실행시킨다.
    $ chmod +x pub.py
    $ rosrun my_pkg1 pub.py
    $ rosrun [패키지이름] [실행할프로그램]

4. Launch 파일 기초

launch파일 사용하기

  • $ roslaunch
    *.launch파일 내용에 따라 여러 노드들을 한꺼번에 실행시킬 수 있다.
  • roslaunch 사용법
    $ roslaunch [패키지이름] [실행시킬 launch파일 이름]
  • e.g) $ roslaunch my_pkg1 aaa.launch
  • 이때 [실행시킬 launch 파일]은 반드시 패키지에 포함된 launch 파일이어야 함.

*.launch파일

  • roslaunch 명령어를 이용하여 많은 노드를 동시에 실행시키기 위한 파일
  • 실행시킬 노드들의 정보가 XML 형식으로 기록되어 있음.

5. Launch 파일 tag 활용

*.launch에서 사용하는 Tag : node

node 태그

  • 실행할 node 정보를 입력할 때 사용되는 태그
    <node pkg="패키지명" type ="노드가 포함된 소스파일 명" name="노드 이름" />
  • e.g
    <node pkg="my_pkg1" type="pub.py" name="pub_node" />
  • 속성
    • pkg: 실행시킬 노드의 패키지 이름을 입력하는 속성
      • 반드시 빌드된 패키지의 이름을 입력해야함
    • type: 노드의 소스코드가 담긴 파이썬 파일의 이름을 입력하는 속성
      • 이때 파이썬.py 파일은 반드시 실행권한이 있어야 한다
      • 실행권한이 없을 시 다음 에러 발생
        ERROR: cannot launch node of type [패키지명/소스파일명]: can't locate node [소스파일명] in package [패키지명]
    • name: 노드의 이름을 입력하는 속성
      • 소스코드에서 지정한 노드의 이름을 무시하고 launch파일에 기록된 노드의 이름으로 노드가 실행됨.

include 태그

  • 다른 launch 파일을 불러오고 싶을 때 사용하는 태그
    <include file= "같이실행할 *.launch파일경로 />
  • e.g)
    <include file="../cam/cam_test.launch /">
    <include file="$(find sub_cam)/src/launch/aaa.launch" />
  • 속성
    • file: 함께 실행시킬 *.launch파일의 경로를 입력하는 속성

launch 파일의 위치

launch 파일 생성

  • 패키지 디렉토리 아래에 'launch' 라는 디렉토리를 만들고
    • 그 안에 .launch 확장자의 파일을 만들어야 함

launch 파일 작성

  • 여러 노드를 함께 실행시킬 때 편리
    • $ roslaunch [package_name] [file.launch]
    • 다수의 노드를 한꺼번에 실행 가능
    • 파라미터 값을 노드에 전달 가능
  • launch파일 작성
    • $ vi gedit pub-sub.launch
    <launch>
        <node pkg="turtlesim" type="turtlesim_node" name="turtle_sum_node" />
        <node pkg="my_pkg1" type="pub.py" name="pub_node"/>
        <node pkg="my_pkg1" type="sub.py" name="sub_node" output="screen" />
    </launch>
    • 패키지가 turtlesim이고 프로그램 이름은 turtlesim_node이고 걔의 이름은 turtlesim_node이다
    • 패키지가 my_pkg1이고 프로그램 이름은 pub.py이고 걔의 이름은 pub_node이다
    • 패키지가 my_pkg1이고 프로그램 이름은 sub.py이고 걔의 이름은 sub_node이다

launch 파일 실행

  • launch파일 실행 방법
    • $roslaunch my_pkg1 pub-sub.launch
  • $ roslaunch 명령을 사용할 때는
    • 별도로 $ roscore 명령을 실행할 필요가 없다
    • 내부적으로 roscore가 자동으로 실행된다

정리

$ cd ~/xycar_ws/src/my_pkg1
$ mkdir launch
$ cd ~/xycar_ws/src/my_pkg1/launch
$ vi pub-sub.launch
$ cm
$ roslaunch my_pkg1 pub-sub.launch

*.launch에서 사용하는 Tag: param

  • param 태그
    • ROS 파라미터 서버에 변수를 등록하고 그 변수에 값을 설정하기 위한 태그
      <param name="변수의 이름" type="변수의 타입" value="변수 값" />
  • 속성
    • name: 등록할 변수의 이름
    • type: 등록할 변수의 타입. 사용할 수 있는 타입의 종류는 str,int,double,bool,yaml
    • value: 등록할 변수의 값
  • ROS 파라미터 서버에 등록된 변수는 노드 코드에서 불러와 사용할 수 있음

launch 파일에서 파리미터 전달 예시

  • launch 파일을 새로 만든다
    • $vi pub-sub-param.launch
    <launch>
      <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node"/>
      <node pkg="my_pkg1" type="pub_param.py" name="node_param">
          <param name="circle_size" value="2"/>
      </node>
      <node pkg="my_pkg1" type="sub.py" name="sub_node" output="screen"/>
    </launch>
    • 패키지 이름 = my_pkg1
    • 타입(소스코드 파일) = pub_param.py
    • 노드 이름 = node_param
    • 파라미터 이름 = circle_size
    • 파라미터 값 = 2

0개의 댓글