🐢

ROS 환경 구축 & 기본 정리

Tags
ROS
ID matched
Created
Mar 27, 2023 03:08 PM
Last Updated
Last updated July 15, 2023
 
 
 

1. ROS

1. 개념

  • 로봇 소프트웨어를 개발하는데 필요한 소프트웨어의 집합체
  • 각종 센서와 모터를 프로그래머가 편하게 사용할 수 있도록 지원
  • 표준화된 통신 프로토콜을 따르는 이기종간의 메시지 교환이 가능
  • 통신은 토픽의 발행 및 구독 기반의 메시지 교환 형식으로 진행
 

2. 용어

  • 마스터 노드 사이의 통신을 총괄 관리(ROS Core)
  • 노드(node) 실행 가능한 최소 단위의 프로세스으로서 토픽을 주고 받는 통신 주체
  • 토픽(topic) 노드간에 통신할 수 있는 채널 (일방적이거나 지속적, 1:1과 N:N 통신 가능)
  • 메시지(message) 통신되는 실제 데이터
  • 발행자 토픽을 만들어 보내는 노드
  • 구독자 토픽을 받는 노드
  • 패키지(package) 하나 이상의 노드와 노드실행을 위한 정보 등을 묶어놓은 것
 
 

2. ROS 설치

  • 설치는 http://wiki.ros.org/melodic/Installation/Ubuntu를 참고하면 된다
    • sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' cat /etc/apt/sources.list.d/ros-latest.list sudo apt install curl # if you haven't already installed curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - sudo apt update sudo apt install ros-melodic-desktop-full echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential sudo rosdep init rosdep update
  • 설치 이후에 roscore를 입력하여 정상적으로 작동하는지 확인해본다
    • notion image
 
 

3. 워크스페이스 생성

  • 원하는 이름으로 워크스페이스를 생성 후 빌드한다
    • mkdir -p ~/${WORK_SPACE_NAME}/src # mkdir -p ~/ros_ws/src cd ${WORK_SPACE_NAME} # cd ~/ros_ws catkin_make # ROS 환경 설정 및 빌드 ll # build, devel 폴더 생성 확인
      notion image
  • .bashrc 파일에 다음의 내용을 추가해준 뒤, source ~/.bashrc로 설정을 업데이트한다
    • alias cm='cd ~/ros_ws&& catkin_make' alias cs='cd ~/ros_ws/src' source /opt/ros/melodic/setup.bash source ~/ros_ws/devel/setup.bash export ROS_MASTER_URI=http://localhost:11311 export ROS_HOSTNAME=localhost
  • 환경변수 목록을 확인하기 위해 printenv | grep ROS을 입력한다
    • notion image
 
 

4. turtle_sim 예제 실행

  • 터미널은 4개의 영역으로 나눈 뒤에, 각각 다음의 명령어를 실행한다
    • notion image
  • roscore 마스터의 실행
  • rosrun turtlesim turtlesim_node turtlesim 노드 실행
  • rosrun turtlesim turtle_teleop_key 키보드로 turtlesim를 제어할 수 있는 노드 실행
  • 다음의 명령어를 실행할 수 있다
    • rqt_graph 시각적으로 노드 및 토픽 흐름 확인하기
      • notion image
    • rosnode list 노드 목록 확인
      • notion image
    • rostopic list 토픽 목록 확인
      • notion image
    • rostopic list -v 토픽 목록 자세히 보기
      • notion image
    • rostopic echo /turtle1/cmd_vel 특정 토픽의 메시지 리스닝하기
      • notion image
    • rostopic type /turtle1/cmd_vel 특정 토픽의 메시지 타입 보기
      • notion image
    • rosmsg show geometry_msgs/Twist 특정 메시지의 형식 보기
      • notion image
    • rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 1회성으로 토픽을 발행해보기
      • notion image
    • rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 지속적으로 토픽을 발행해보기
      • notion image
 
 

5. 커스텀 패키지 제작

1. 패키지 생성

  • 아래의 명령어로 새로운 패키지를 생성한다
    • cd ~/${WORK_SPACE_NAME}/src # cd ~/ros_ws/src catkin_create_pkg ${PACKGE_NAME} std_msgs rospy # catkin_create_pkg init_pkg std_msgs rospy cd ~/${WORK_SPACE_NAME} # cd ~/ros_ws catkin_make
  • 아래의 명령어로 패키지가 제대로 생성되었는지 확인한다
    • rospack list | grep init_pkg
      • notion image
    • rospack find init_pkg
      • notion image
    • rospack depends1 init_pkg
      • notion image

2. 파일 작성

  • ~/ros_ws/src/init_pkg/src 폴더 하위에 talker.pylistener.py 작성
    • #!/usr/bin/env python # license removed for brevity import rospy from std_msgs.msg import String from geometry_msgs.msg import Twist def talker(): pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz 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 while not rospy.is_shutdown(): rospy.loginfo(msg) pub.publish(msg) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass
      talker.py
      #!/usr/bin/env python import rospy from std_msgs.msg import String from turtlesim.msg import Pose def callback(data): rospy.loginfo(rospy.get_caller_id() + ":: %.2f %.2f", data.x, data.y) def listener(): rospy.init_node('listener', anonymous=True) rospy.Subscriber("/turtle1/pose", Pose, callback) rospy.spin() if __name__ == '__main__': listener()
      listener.py
  • cpp 관련 코드는 다음과 같이 작성하면 된다
    • #include "ros/ros.h" #include "std_msgs/String.h" #include "geometry_msgs/Twist.h" #include <sstream> int main(int argc, char **argv) { ros::init(argc, argv, "talker"); ros::NodeHandle n; ros::Publisher chatter_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1); ros::Rate loop_rate(1); while (ros::ok()) { geometry_msgs::Twist msg; msg.linear.x = 2.0; msg.linear.y = 2.0; msg.linear.z = 2.0; msg.angular.x = 0.0; msg.angular.y = 0.0; msg.angular.z = 1.8; chatter_pub.publish(msg); loop_rate.sleep(); } return 0; }
      talker.cpp
      #include "ros/ros.h" #include "std_msgs/String.h" #include "turtlesim/Pose.h" #include <iostream> void chatterCallback(turtlesim::Pose msg) { ROS_INFO("[L] %.4f, %.4f", msg.x, msg.y); } int main(int argc, char **argv) { ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe<turtlesim::Pose>("/turtle1/pose", 1000, chatterCallback); ros::spin(); return 0; }
      listener.cpp
  • 스크립트를 실행해서 정상적으로 진행하는지 확인한다
    • python talker.py
      • notion image
    • python listener.py
      • notion image
 
 

6. 실행

1. rosrun를 통한 실행

  • chmod +x *.py로 해당 파일에 실행권한을 추가한 후, ll 명령어로 확인한다
    • notion image
  • 위에 한 것과 같이, 터미널을 4개 영역으로 나누어 실행한 뒤 각각 명령어를 입력한다.
    • roscore 마스터의 실행
    • rosrun turtlesim turtlesim_node turtlesim 노드 실행
    • rosrun init_pkg talker.py 거북이를 회전하게 만드는 노드 실행행
    • rosrun init_pkg listener.py /turtle1/pose 정보를 받아오는 노드 실행행

2. roslaunch를 통한 실행

  • ~/ros_ws/src/init_pkg/launch 폴더 생성 후 talk-listen.launch 작성
    • <launch> <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node"/> <node pkg="init_pkg" type="talker.py" name="talk_node"/> <node pkg="init_pkg" type="listener.py" name="listen_node" output="screen"/> </launch>
  • roslaunch init_pkg talk-listen.launch로 실행
    • notion image

3. param를 적용한 roslaunch 실행

  • ~/ros_ws/src/init_pkg/launch 폴더 하위에 talk-listen-param.launch 작성
    • <launch> <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node"/> <node pkg="init_pkg" type="talk_param.py" name="node_param"> <param name="circle_size" value="5" /> </node> <node pkg="init_pkg" type="listener.py" name="listen_node" output="screen"/> </launch>
  • ~/ros_ws/src/init_pkg/src 폴더 하위에 talk_param.py 작성
    • #!/usr/bin/env python # license removed for brevity import rospy from std_msgs.msg import String from geometry_msgs.msg import Twist def talker(): pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz msg = Twist() # msg.linear.x = 2.0 linear_X = rospy.get_param('~circle_size') msg.linear.x = linear_X 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 while not rospy.is_shutdown(): rospy.loginfo(msg) pub.publish(msg) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass
  • chmod +x talk_param.py로 실행 권한 주기
  • roslaunch init_pkg talk-listen-param.launch로 실행
    • notion image