xycar_lidar
rosmsg show sensor_msgs/LaserScan
# Output
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities
catkin_create_pkg my_lidar std_msgs rospy
lidar_scan.py
lidar_scan.launch
# lidar_scan.py
#!/usr/bin/env python
import rospy
import time
from sensor_msgs.msg import LaserScan
lidar_points = None
def lidar_callback(data):
global lidar_points
lidar_points = data.ranges
rospy.init_node('my_lidar', anonymous=True)
rospy.Subscriber("/scan", LaserScan, lidar_callback, queue_size=1)
while not rospy.is_shutdown():
if lidar_points == None:
continue
rtn = ""
for i in range(12):
rtn += str(format(lidar_points[i*30],'.2f')) + ", "
print(rtn[:-2])
time.sleep(1.0)
# lidar_scan.launch
<launch>
<node name="xycar_lidar" pkg="xycar_lidar" type="xycar_lidar" output="screen">
<node name="my_lidar" pkg="my_lidar" type="lidar_scan.py" output="screen"/>
</launch>
rviz_lidar
패키지 생성# 위치는 ~/xycar_ws/src
catkin_create_pkg rviz_lidar rospy tf geometry_msgs urdf rviz xacro
lidar_3d.rviz
(자동 생성)lidar_3d.launch
# lidar_3d.launch
<launch>
<node name="xycar_lidar" pkg="xycar_lidar" type="xycar_lidar" output="screen">
<param name="serial_port" type="string" value="/dev/ttyRPL"/>
<param name="serial_baudrate" type="int" value="115200"/>
<param name="frame_id" type="string" value="laser"/>
<param name="inverted" type="bool" value="false"/>
<param name="angle_compensate" type="bool" value="true"/>
<param name="scan_mode" type="string" value="Express"/>
</node>
<node name="my_lidar" pkg="my_lidar" type="lidar_scan.py" output="screen"/>
</launch>
rosbag
프로그램을 통해 /scan
토픽을 대신 발행해 사용할 수 있다./scan
토픽을 저장해 놓은 파일(lidar_topic.bag
)을 사용해/scan
토픽을 발행할 수 있다.# lidar_3d_rosbag.launch
<launch>
<!-- rviz display -->
<node name="rviz_visualizer" pkg="rviz" type="rviz" required="true"
args="-d $(find rviz_lidar)/rviz/lidar_3d.rviz"/>
<node name="rosbag_play" pkg="rosbag" type="play" output="screen"
required="true" args="$(find rviz_lidar)/src/lidar_topic.bag"/>
</launch>
roslaunch rviz_lidar lidar_3d.launch
# 혹은
roslaunch rviz_lidar lidar_3d_rosbag.launch
뭔가 움직인다.
rviz_lidar
사용lidar_range.launch
lidar_range.py
lidar_range.vriz
# lidar_range.launch
<launch>
<!-- rviz display -->
<node name="rviz_visualizer" pkg="rviz" type="rviz" required="true"
args="-d $(find rviz_lidar)/rviz/lidar_range.rviz"/>
<node name="lidar_range" pkg="rviz_lidar" type="lidar_range.py"/>
</launch>
# lidar_range.py
#!/usr/bin/env python
import serial, time, rospy
from sensor_msgs.msg import Range
from std_msgs.msg import Header
rospy.init_node('lidar_range')
pub1 = rospy.Publisher('scan1', Range, queue_size=1)
pub2 = rospy.Publisher('scan2', Range, queue_size=1)
pub3 = rospy.Publisher('scan3', Range, queue_size=1)
pub4 = rospy.Publisher('scan4', Range, queue_size=1)
msg = Range()
h = Header()
h.frame_id = "sensorXY"
msg.header = h
msg.radiation_type = Range().ULTRASOUND
msg.min_range = 0.02
msg.max_range = 2.0
msg.field_of_view = (30.0/180.0)*3.14
while not rospy.is_shutdown():
msg.header.stamp = rospy.Time.now()
msg.range = 0.4
pub1.publish(msg)
msg.range = 0.8
pub2.publish(msg)
msg.range = 1.2
pub3.publish(msg)
msg.range = 1.6
pub4.publish(msg)
time.sleep(0.2)
lidar_range
/scan1
, /scan2
, /scan3
, /scan4
Range
roslaunch rviz_lidar lidar_range.launch
이런 식으로 표시할 수 있다.
이런걸 만들어 볼 것.
rviz_lidar
lidar_urdf.launch
lidar_urdf.py
, lidar_topic.bag
lidar_urdf.urdf
lidar_urdf.rviz
# lidar_urdf.launch
<launch>
<param name="robot_description"
textfile="$(find rviz_lidar)/urdf/lidar_urdf.urdf"/>
<param name="use_gui" value="true"/>
<node name="rviz_visualizer" pkg="rviz" type="rviz" required="true"
args="-d $(find rviz_lidar)/rviz/lidar_urdf.rviz"/>
<node name="robot_state_publisher" pkg="robot_state_publisher"
type="state_publisher"/>
<node name="rosbag_play" pkg="rosbag" type="play" output="screen"
required="true" args="$(find rviz_lidar)/src/lidar_topic.bag"/>
<node name="lidar" pkg="rviz_lidar" type="lidar_urdf.py" output="screen"/>
</launch>
# lidar_urdf.py
#!/usr/bin/env python
import serial, time, rospy
from sensor_msgs.msg import LaserScan
from sensor_msgs.msg import Range
from std_msgs.msg import Header
lidar_points = None
def lidar_callback(data):
global lidar_points
lidar_points = data.ranges
rospy.init_node('lidar')
rospy.Subscriber("/scan", LaserScan, lidar_callback, queue_size=1)
pub1 = rospy.Publisher('scan1', Range, queue_size=1)
pub2 = rospy.Publisher('scan2', Range, queue_size=1)
pub3 = rospy.Publisher('scan3', Range, queue_size=1)
pub4 = rospy.Publisher('scan4', Range, queue_size=1)
msg = Range()
h = Header()
msg.radiation_type = Range().ULTRASOUND
msg.min_range = 0.02
msg.max_range = 2.0
msg.field_of_view = (30.0/180.0)*3.14
while not rospy.is_shutdown():
#msg.header.stamp = rospy.Time.now()
if lidar_points == None:
continue
h.frame_id = "front"
msg.header = h
msg.range = lidar_points[90]
pub1.publish(msg)
h.frame_id = "right"
msg.header = h
msg.range = lidar_points[180]
pub2.publish(msg)
h.frame_id = "back"
msg.header = h
msg.range = lidar_points[270]
pub3.publish(msg)
h.frame_id = "left"
msg.header = h
msg.range = lidar_points[0]
pub4.publish(msg)
time.sleep(0.5)
# lidar_urdf.urdf
<?xml version="1.0"?>
<robot name="xycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
<link name="base_link"/>
<link name="baseplate">
<visual>
<material name="red"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.2 0.2 0.07"/>
</geometry>
</visual>
</link>
<joint name="base_link_to_baseplate" type="fixed">
<parent link="base_link"/>
<child link="baseplate"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<link name="front"/>
<joint name="baseplate_to_front" type="fixed">
<parent link="baseplate"/>
<child link="front"/>
<origin rpy="0 0 0" xyz="0.1 0 0"/>
</joint>
<link name="back"/>
<joint name="baseplate_to_back" type="fixed">
<parent link="baseplate"/>
<child link="back"/>
<origin rpy="0 0 3.14" xyz="-0.1 0 0"/>
</joint>
<link name="left"/>
<joint name="baseplate_to_left" type="fixed">
<parent link="baseplate"/>
<child link="left"/>
<origin rpy="0 0 1.57" xyz="0 0.1 0"/>
</joint>
<link name="right"/>
<joint name="baseplate_to_right" type="fixed">
<parent link="baseplate"/>
<child link="right"/>
<origin rpy="0 0 -1.57" xyz="0 -0.1 0"/>
</joint>
<material name="black">
<color rgba="0.0 0.0 0.0 1.0"/>
</material>
<material name="blue">
<color rgba="0.0 0.0 1.8 1.0"/>
</material>
<material name="green">
<color rgba="0.0 0.8 0.0 1.0"/>
</material>
<material name="red">
<color rgba="0.8 0.0 0.0 1.0"/>
</material>
<material name="white">
<color rgba="1.0 1.0 1.0 1.0"/>
</material>
<material name="orange">
<color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
</material>
</robot>
# 실행
roslaunch rviz_lidar lidar_urdf.launch
라이다 센서의 감지 범위를 Range로 표현할 수 있었다.