ROS2 turtle keyboard 만들기
참고 경로
/opt/ros/foxy/share
거북이 실행
1번 터미널에서
ros2 run turtlesim turtlesim_node
거북이 키보드로 움직이기
2번 터미널에서
ros2 run turtlesim turtle_teleop_key
거북이 원격 조정 코드 만들기
ros2 pkg create turtle_pkg --build-type ament_python
키보드 입력을 받기위한 사용자 라이브러리
cd turtle_pkg/turtle_pkg 로 가서 getchar.py
import os, time, sys, termios, atexit, tty
from select import select
# class for checking keyboard input
class Getchar:
def __init__(self):
# Save the terminal settings
self.fd = sys.stdin.fileno()
self.new_term = termios.tcgetattr(self.fd)
self.old_term = termios.tcgetattr(self.fd)
# New terminal setting unbuffered
self.new_term[3] = (self.new_term[3] & ~termios.ICANON & ~termios.ECHO)
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term)
# Support normal-terminal reset at exit
atexit.register(self.set_normal_term)
def set_normal_term(self):
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term)
def getch(self): # get 1 byte from stdin
""" Returns a keyboard character after getch() has been called """
return sys.stdin.read(1)
def chk_stdin(self): # check keyboard input
""" Returns True if keyboard character was hit, False otherwise. """
dr, dw, de = select([sys.stdin], [], [], 0)
return dr
cd turtle_pkg 에서 remote_turtle.py
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
from .getchar import Getchar
msg = '''
Remote Control Turtle
'w' for forward
's' for backward
'a' for turn left
'd' for turn right
' ' for stop move
'Q' for terminate code
'''
class Remote_Turtle(Node):
def __init__(self):
super().__init__('remote_turtle')
self.pub = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
def main(args=None):
rclpy.init(args=args)
node = Remote_Turtle()
kb = Getchar()
tw = Twist()
#pub = node.create_publisher(Twist, '/turtle1/cmd_vel', 10)
try:
print(msg)
while rclpy.ok():
key = kb.getch()
if key == 'w':
print("forward")
tw.linear.x = tw.angular.z = 0.0
tw.linear.x = 2.0
elif key == 's':
print("backward")
tw.linear.x = tw.angular.z = 0.0
tw.linear.x = -2.0
elif key == 'a':
print("turn left")
tw.linear.x = tw.angular.z = 0.0
tw.angular.z = 2.0
elif key == 'd':
print("turn right")
tw.linear.x = tw.angular.z = 0.0
tw.angular.z = -2.0
elif key == ' ':
print("stop")
tw.linear.x = tw.angular.z = 0.0
elif key == 'Q':
print("Bye~")
break
else:
pass
node.pub.publish(tw)
# 위에 29번째 줄(pub = self.create_publisher(Twist, ‘/turtle1/cmd_vel’, 10))을 주석해제했을 때는 위의 내용을 주석하고, 아래의 줄 내용을 주석해제 한다.
#pub.publish(tw)
except KeyboardInterrupt:
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
cd .. 해서 setup.py에 ‘remote_turtle = turtle_pkg.remote_turtle:main’, 넣기
entry_points={
'console_scripts': [
'remote_turtle = turtle_pkg.remote_turtle:main',
],
},
cd turtle_pkg 가서 move_circle.py
거북이 원 그리기
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class MoveCircle(Node):
def __init__(self):
super().__init__('move_circle')
self.pub = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
def main(args=None):
rclpy.init(args=args)
node = MoveCircle()
tw = Twist()
tw.linear.x = 2.0
tw.angular.z = 2.0
try:
while rclpy.ok():
node.pub.publish(tw)
except KeyboardInterrupt:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
cd .. 해서 setup.py 에 ‘move_circle = turtle_pkg.move_circle:main’,
entry_points={
'console_scripts': [
'remote_turtle = turtle_pkg.remote_turtle:main',
'move_circle = turtle_pkg.move_circle:main',
],
},
cd turtle_pkg 해서 move_circle_2.py
거북이 입력 받아 원 그리기
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class MoveCircle(Node):
def __init__(self):
super().__init__('move_circle_2')
self.pub = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
def main(args=None):
rclpy.init(args=args)
node = MoveCircle()
tw = Twist()
tw.linear.x = float(input("input linear.x : "))
tw.angular.z = float(input("input angular.z : "))
try:
while rclpy.ok():
node.pub.publish(tw)
except KeyboardInterrupt:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
cd .. 해서 setup.py 에 ‘move_circle = turtle_pkg.move_circle:main’,
entry_points={
'console_scripts': [
'remote_turtle = turtle_pkg.remote_turtle:main',
'move_circle = turtle_pkg.move_circle:main',
'move_circle_2 = turtle_pkg.move_circle_2:main',
],
},
cd turtle_pkg 해서 get_turtle_pose.py
거북이 위치값 받기
import rclpy
from rclpy.node import Node
from turtlesim.msg import Pose
class SubTurtlePose(Node):
def __init__(self):
super().__init__("get_turtle_pose")
self.create_subscription(
Pose, "/turtle1/pose", self.get_pose, 10
)
self.turtle_pose = Pose()
def get_pose(self, msg):
self.turtle_pose = msg
# print("x = %s, y = %s, th = %s" % (msg.x, msg.y, msg.theta))
def main(args=None):
rclpy.init(args=args)
node = SubTurtlePose()
# rclpy.spin(node)
try:
while rclpy.ok():
rclpy.spin_once(node, timeout_sec=0.1)
print("x = %s, y = %s, th = %s" % (node.turtle_pose.x, node.turtle_pose.y, node.turtle_pose.theta))
except KeyboardInterrupt:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
cd .. 해서 setup.py에 ‘get_turtle_pose = turtle_pkg.get_turtle_pose:main’, 넣기
entry_points={
'console_scripts': [
'remote_turtle = turtle_pkg.remote_turtle:main',
'move_circle = turtle_pkg.move_circle:main',
'move_circle_2 = turtle_pkg.move_circle_2:main',
'get_turtle_pose = turtle_pkg.get_turtle_pose:main',
],
},
ROS2 usb cam 체험
sudo apt install ros-foxy-usb-cam
sudo apt install ros-foxy-rqt*
아래와 같이 하면 노트북 캠에 불빛이 남
ros2 run usb_cam usb_cam_node_exe
새 터미널에서 아래와 같이 하면 캠 화면이 보임
rqt
근데 난 안됨. 무슨 설정을 더 해야 하는 건가?
Comments