[ROS] 패키지 생성과 실행 방법 (How to create and run packages)

Sinaenjuni·2023년 3월 27일
0

ROS

목록 보기
2/12

Package (패키지) 생성하기

1. 패키지 생성

$ caktin_create_pk <package_name> <dependencise>

$ cd ~/ros_ws/src
$ caktin_create_pk package1 std_msgs rospy

package1은 만들고자 하는 패키지의 이름이고 std_msgs와 rospy는 만드는 패키지에 의존되는 패키지들이다. std_msgs같은 경우는 ros 시스템에서 제공하는 기본적은 메시지들의 형태를 사용할 수 있도록 도와주고, rospy의 경우 python을 이용한 ros 개발을 도와주는 패키지이다. rospy의 경우 패키지 디렉터리 안에 src 디렉터리가 생성된다. dependencise는 패키지를 생성할 때 지정하지 않아도 된다.

2. 빌드

$ cd ~/ros_ws
$ catkin_make

Workspace에서 변경된 내용을 시스템에 적용하는 과정이다.

3. 빌드된 패키지 확인

$ rospack find <package_name>

# package 이름을 통해 위치를 보여준다.
sin@Ubuntu1804:~/ros_ws/src/my_turtlesim$ rospack find my_turtlesim 
/home/sin/ros_ws/src/my_turtlesim

$ rospack depends <package_name>

# package와 의존성이 있는 패키지 정보를 보여준다.
sin@Ubuntu1804:~/ros_ws/src/my_turtlesim$ rospack depends my_turtlesim 
catkin
genmsg
genpy
cpp_common
rostime
roscpp_traits
roscpp_serialization
message_runtime
gencpp
geneus
gennodejs
genlisp
message_generation
rosbuild
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
ros_environment
rospack
roslib
rospy

$ roscd <package_name>

# 해당 package의 디렉터리로 이동한다.
sin@Ubuntu1804:~/ros_ws/src/my_turtlesim$ roscd my_turtlesim/

패키지 생성 후의 디렉터리 구조

├── ros_ws
    ├── build
    ├── devel
    ├── .catkin_workspace
    └── src
 	 	└── CMakeLists.txt
 		└── package_1
            ├── src (rospy)
	 	    ├── CMakeList.txt
 	 	    └── package.xml

테스트 코드

1. /turtle1/cmd_vel 메시지를 발행하는 Publisher 코드

turtlesim_node를 제어하는 python 코드를 작성한다. turtlesim_node에서 구독중인 /turtle1/cmd_vel topic을 발행하는 코드이다.

sin@Ubuntu1804:~/ros_ws$ rostopic list
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

sin@Ubuntu1804:~/ros_ws$ rostopic info /turtle1/cmd_vel
Type: geometry_msgs/Twist

Publishers: None

Subscribers: 
 * /turtlesim (http://10.211.55.10:34105/)

sin@Ubuntu1804:~/ros_ws$ rosmsg info geometry_msgs/Twist
geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z
#!/usr/bin/env python

import rospy
from geometry_msgs.msg import Twist

rospy.init_node('my_turtlesim_node', anonymous=True) # make node
pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10) # make 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)  
# number of message per 1 second

while not rospy.is_shutdown():  
  # message publish
  pub.publish(msg)
  rate.sleep()
주의! 소스코드 파일 작성할 때, 실행 권한이 부여되어 있는지 확인해야 한다.
# 실행권한 부여
$ chmod +x package_name/src/*.py

다음의 명령을 통해 작성한 코드를 실행시킬 수 있다.

# roscore 실행
$ roscore
# turtlesim_node 실행
$ rosrun turtlesim turtlssim_node
# 위에서 작성한 코드 실행
$ rosrun package1 *.py

2. /turtle1/cmd_vel 메시지를 구독하는 Subscriber 코드

$ rostopic list
# 시스템에 사용중인 모든 토픽의 이름을 확인한다.
$ rostopic type /turtle1/pose
# 토픽의 타입을 확인한다.
$ rosmsg show turtlesim/Pose
# 메시지의 데이터 타입을 확인한다.
$ rostopic ehco /turtle1/pose
# 발행중인 메시지의 내용을 확인한다.
#!/usr/bin/env python

import rospy
from turtlesim.msg import Pose

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

rospy.init_node("my_turtle_sub_node", anonymous=True) 
# make node
rospy.Subscriber("/turtle1/pose", Pose, callback) 
# make object of subscriber and call method if receive a message
rospy.spin() 
# infinite loop

launch file

여러 node를 한번에 실행시키는 방법으로 XML로 정의한다.

<node pkg="package_name" type="source_file_name" name="node_name" />
# 예시
<node pkg="my_pkg1" type="pub.py" name="pub_node" />
  • pkg: 실행하고자 하는 빌드된 패키지의 이름을 입력한다.
  • type: 노드의 코드가 기록된 파일의 이름을 입력한다.
  • name: 노드의 이름을 입력한다. 코드에 작성된 이름을 무시하고 입력된 이름으로 노드가 실행된다.

include tag

<include file="another launch file path" />
# 예시
<include file="../cam/cam_test.launch" />
  • launch 파일에서 다른 launch 파일을 연결하는 방법이다.

directory structure

├── ros_ws
    ├── build
    ├── devel
    ├── .catkin_workspace
    └── src
 	 	└── CMakeLists.txt
 		└── package_1
            ├── src (rospy)
        	│   └── src (rospy)
            ├── launch (rospy)
            │	└── *.launch
	 	    ├── CMakeList.txt
 	 	    └── package.xml
  • launch 디렉터리는 자동으로 생성되지 않는다. 직접 생성해야 한다.

launch tag

<launch>
<node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node" />
<node pkg="my_pkg1" type="pub.py" name="pub_node" />
<node pkg="my_pkg1" type="sub.py" name="sub_node" output="screen"/>
</launch>
  • pub-sub.launch 파일의 내용
$ roslaunch my_pkg pub-sum.launch
  • launch 파일을 통해 node를 실행하는 경우 roscore는 실행시키지 않아도 된다.

param tag

ROS 내의 파라미터 서버에 변수를 등록하고 초기화 하는 역할을 수행한다. 파라미터 서버에 등록된 변수는 노드 코드에서 사용할 수 있다.

<node pkg="package_name" type="source_file_name" name="node_name" output="screen">
  <param name="age" type="int" value="11"/>
</node>
  • name: 등록할 변수의 이름을 의미한다.
  • type: 변수의 데이터 타입을 의미한다.
  • value: 변수에 저장할 값을 의미한다.
improt rospy
rospy.init_node('node_name")
print(rospy.get_param("~age")

위 처럼 파라미터 서버에 등록된 변수는 ~변수명을 통해서 접근이 가능하다.

0개의 댓글