Mac M1 UTM Ubuntu22.04(Humble) ROS2 Turtle Study with Youtube
ROS2 Turtle Study
참고 Youtube : ROS2 Tutorial - ROS2 Humble
vim ~/.bashrc
위와 같이 들어가서
source /opt/ros/humble/setup.bash
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash
source ~/ros2_ws/install/setup.bash
위와 같이 작성한다
source ~/.bashrc
위와 같이 반영한다
59.6.0 버전이었는데 58.2.0 버전으로 다운그레이드 한다
참고
sudo apt install python3-pip
pip3 list | grep setuptools
pip install setuptools==58.2.0
Turtlesim Install
Start
ros2 run turtlesim turtlesim_node
Use
ros2 run turtlesim turtle_teleop_key
각 명령의 하위 명령을 사용하면 노드와 관련 주제, 서비스, 작업을 볼 수 있습니다.
ros2 node list
ros2 topic list
ros2 service list
ros2 action list
기타
ros2 topic list
ros2 topic info /turtle1/cmd_vel
ros2 interface show geometry_msgs/msg/Twist
위와 같이 interface show 시 아래와 같이 나온다
Vector3 linear
float64 x
float64 y
float64 z
Vector3 angular
float64 x
float64 y
float64 z
이번엔 이렇게 해보자
ros2 service type /turtle1/set_pen
ros2 interface show turtlesim/srv/SetPen
위와 같이 interface show 시 아래와 같이 나온다
uint8 r
uint8 g
uint8 b
uint8 width
uint8 off
Code Start
mkdir ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create my_robot_controller --build-type ament_python --dependencies rclpy
cd ~/ros2_ws/src/my_robot_controller/my_robot_controller
touch my_first_node.py
chmod +x my_first_node.py
my_first_node.py
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
class MyNode(Node):
def __init__(self):
super().__init__("first_node")
self.counter_ = 0
self.create_timer(1.0, self.timer_callback)
def timer_callback(self):
self.get_logger().info("Hello from ROS2~~~" + str(self.counter_))
self.counter_ += 1
def main(args=None):
rclpy.init(args=args) # start
node = MyNode()
rclpy.spin(node)
rclpy.shutdown() # end
if __name__ == "__main__":
main()
visual studio code 에 확장:마켓플레이스 에서 ROS 설치하면 좋다(Microsoft꺼)
setup.py에서 entry_points={‘console_scripts’: [],}, 안에 아래와 같이 넣고
entry_points={
'console_scripts': [
"test_node = my_robot_controller.my_first_node:main"
],
},
cd ~/ros2_ws
로 가서
colcon build
source ~/.bashrc
를 하고
ros2 run my_robot_controller 하고 탭을 치면 test_node 가 나와서
ros2 run my_robot_controller test_node
위와 같이 치면 위에서 my_first_node.py 파일의 main이 실행된다
근데 매번 파일 고치면 colcon build를 해줘야 하는 번거러움이 있다. 그래서
colcon build --symlink-install
source ~/.bashrc
를 해준다
cd ~/ros2_ws/src/my_robot_controller/my_robot_controller
touch draw_circle.py
chmod +x draw_circle.py
draw_circle.py
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class DrawCircleNode(Node):
def __init__(self):
super().__init__("draw_circle")
self.cmd_vel_pub_ = self.create_publisher(Twist, "/turtle1/cmd_vel", 10)
self.timer_ = self.create_timer(0.5, self.send_velocity_command)
self.get_logger().info("Draw Start~~~")
def send_velocity_command(self):
msg = Twist()
msg.linear.x = 2.0
msg.angular.z = 1.0
self.cmd_vel_pub_.publish(msg)
def main(args=None):
rclpy.init(args=args) # start
node = DrawCircleNode()
rclpy.spin(node)
rclpy.shutdown() # end
package.xml에
<depend>rclpy</depend>
<depend>geometry_msgs</depend>
<depend>turtlesim</depend>
setup.py에서 entry_points={‘console_scripts’: [],}, 안에 아래와 같이 넣고
entry_points={
'console_scripts': [
"test_node = my_robot_controller.my_first_node:main",
"draw_circle = my_robot_controller.draw_circle:main"
],
},
cd ~/ros2_ws/src/my_robot_controller/my_robot_controller
touch pose_subscriber.py
chmod +x pose_subscriber.py
pose_subscriber.py
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from turtlesim.msg import Pose
class PoseSubscriberNode(Node):
def __init__(self):
super().__init__("pose_subscriber")
self.pose_subscriber_ = self.create_subscription(
Pose, "/turtle1/pose", self.pose_callback, 10
)
def pose_callback(self, msg: Pose):
self.get_logger().info("(" + str(msg.x) + ", " + str(msg.y) + ")")
def main(args=None):
rclpy.init(args=args) # start
node = PoseSubscriberNode()
rclpy.spin(node)
rclpy.shutdown() # end
setup.py에서 entry_points={‘console_scripts’: [],}, 안에 아래와 같이 넣고
entry_points={
'console_scripts': [
"test_node = my_robot_controller.my_first_node:main",
"draw_circle = my_robot_controller.draw_circle:main",
"pose_subscriber = my_robot_controller.pose_subscriber:main"
],
},
cd ~/ros2_ws/src/my_robot_controller/my_robot_controller
touch turtle_controller.py
chmod +x turtle_controller.py
turtle_controller.py
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from turtlesim.msg import Pose
from geometry_msgs.msg import Twist
from turtlesim.srv import SetPen
from functools import partial
class TurtleControllerNode(Node):
def __init__(self):
super().__init__("turtle_controller")
self.previous_x_ = 0
self.cmd_vel_publisher_ = self.create_publisher(
Twist, "/turtle1/cmd_vel", 10
)
self.pose_subscriber_ = self.create_subscription(
Pose, "/turtle1/pose", self.pose_callback, 10
)
self.get_logger().info("Turtle Start~~")
def pose_callback(self, pose: Pose):
cmd = Twist()
if pose.x > 9.0 or pose.x < 2.0 or pose.y > 9.0 or pose.y < 2.0:
cmd.linear.x = 1.0
cmd.angular.z = 0.9
else:
cmd.linear.x = 5.0
cmd.angular.z = 0.0
self.cmd_vel_publisher_.publish(cmd)
if pose.x > 5.5 and self.previous_x_ <= 5.5:
self.previous_x_ = pose.x
self.get_logger().info("Set Color to Red~~")
self.call_set_pen_service(255, 0, 0, 3, 0)
elif pose.x <= 5.5 and self.previous_x_ > 5.5:
self.previous_x_ = pose.x
self.get_logger().info("Set Color to Green~~")
self.call_set_pen_service(0, 255, 0, 3, 0)
def call_set_pen_service(self, r, g, b, width, off):
client = self.create_client(SetPen, "/turtle1/set_pen")
while not client.wait_for_service(1.0):
self.get_logger().warn("Wating for service~~~")
request = SetPen.Request()
request.r = r
request.g = g
request.b = b
request.width = width
request.off = off
future = client.call_async(request)
future.add_done_callback(partial(self.callback_set_pen))
def callback_set_pen(self, future):
try:
response = future.result()
except Exception as e:
self.get_logger().error("Service call failed: %r" % (e, ))
def main(args=None):
rclpy.init(args=args) # start
node = TurtleControllerNode()
rclpy.spin(node)
rclpy.shutdown() # end
setup.py에서 entry_points={‘console_scripts’: [],}, 안에 아래와 같이 넣고
entry_points={
'console_scripts': [
"test_node = my_robot_controller.my_first_node:main",
"draw_circle = my_robot_controller.draw_circle:main",
"pose_subscriber = my_robot_controller.pose_subscriber:main",
"turtle_controller = my_robot_controller.turtle_controller:main"
],
},
Comments