AR tags¶
Note
This section is covered only for DAT160 students.
AR tags (aka Artifitial Reality tags) are QR-code like black and white images which can be created with a unique ID number and used as an identification of a place/object/state in the robot world. In this section, we are not interested in the image process of an AR tag to visualize its representative image but we are interested in creating them, detecting in an environment, identifying and taking an action based on their ID.
Example AR tags¶
There is a specigic package called ar-track-alvar available in ROS enables to create and read AR tags. This package is a part of ros-perception and it is not installed in default with ros_DISTRO-desktop_full installation. However, the VM copy which we provided has this package additionally installed. If you don’t have the package, please run the following commang to install it:
sudo apt install ros-melodic-ar-track-alvar
The official documentation of the ar_track_alvar package is here.
To generate new AR tags run the ROS node: rosrun ar_track_alvar createMarker, give a prefered ID number and leave the dimension/position as default by pressing only Enter without any value entered.
rosrun ar_track_alvar createMarker 4 -s 5 ## Creates Marker4.png 5cm*5cm
To use the created AR tag in real world, you should simply print them out in original size. We are going to use them in the Gazebo environment. Therefore, we have used them as surface meshes on a custom Gazebo model.
Let’s check if you have the necessary models in place:
cd ~/.gazebo/models
ls marker*
## OUTPUT should be:
marker0:
materials meshes model-1_4.sdf model-1_5.sdf model.config model.sdf
marker1:
materials meshes model-1_4.sdf model-1_5.sdf model.config model.sdf
marker2:
materials meshes model-1_4.sdf model-1_5.sdf model.config model.sdf
marker3:
materials meshes model-1_4.sdf model-1_5.sdf model.config model.sdf
marker4:
materials meshes model-1_4.sdf model-1_5.sdf model.config model.sdf
If you cannot list any markers plese download the models folder from follow the link to download the AR tag models.
We are ready to spawn a Turtlebot in a custom world filled with 5 different AR tags.
roslaunch ar_tutorials tb_ar_world.launch
roslaunch ar_tutorials ar_track.launch
rosrun rqt_image_view rqt_image_view
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
rostopic echo /ar_pose_marker
Please analyse the topic and try to capture id of a visible marker through terminal.
<launch>
<arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="x_pos" default="1.0"/>
<arg name="y_pos" default="0.0"/>
<arg name="z_pos" default="0.0"/>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find ar_tutorials)/worlds/custom.world"/>
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
<param name="robot_description" command="$(find xacro)/xacro --inorder $(find turtlebot3_description)/urdf/turtlebot3_$(arg model).urdf.xacro" />
<node pkg="gazebo_ros" type="spawn_model" name="spawn_urdf" args="-urdf -model turtlebot3_$(arg model) -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" />
</launch>
<sdf version="1.4">
<world name="default">
<include>
<uri>model://sun</uri>
</include>
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://marker0</uri>
<pose>0 0 0 0 0 0</pose>
</include>
<include>
<uri>model://marker1</uri>
<pose>0 2 0 0 0 0</pose>
</include>
<include>
<uri>model://marker2</uri>
<pose>0 4 0 0 0 0</pose>
</include>
<include>
<uri>model://marker3</uri>
<pose>0 6 0 0 0 0</pose>
</include>
<include>
<uri>model://marker4</uri>
<pose>0 8 0 0 0 0</pose>
</include>
<!--the light source created in the world file-->
<light type="directional" name="my_light" cast_shadows="false">
<direction xyz="0 0 -1"/>
<specular rgba=".1 .1 .1 1"/>
</light>
</world>
</sdf>
<launch>
<arg name="camera" default="camera" />
<arg name="pi/2" value="1.5707963267948966" />
<arg name="camera_transformation" value="0 0 0 0 0 0" />
<node pkg="tf" type="static_transform_publisher" name="$(arg camera)_base_link3"
args="$(arg camera_transformation) /world camera_rgb_optical_frame 100" />
<arg name="marker_size" default="5" />
<arg name="max_new_marker_error" default="0.08" />
<arg name="max_track_error" default="0.2" />
<arg name="cam_image_topic" default="/camera/rgb/image_raw" />
<arg name="cam_info_topic" default="/camera/rgb/camera_info" />
<arg name="output_frame" default="camera_rgb_optical_frame" />
<node name="ar_track_alvar" pkg="ar_track_alvar" type="individualMarkersNoKinect" respawn="false" output="screen" args="$(arg marker_size) $(arg max_new_marker_error) $(arg max_track_error) $(arg cam_image_topic) $(arg cam_info_topic) $(arg output_frame)" />
</launch>
Subscriber node to /ar_pose_marker¶
Now we can have a template subscriber to get AR tag pose data and take an action according to that.
#!/usr/bin/env python
import rospy
from ar_track_alvar_msgs.msg import AlvarMarkers
detected_markers=set()
markers_in_sight=['a']
def callback(msg):
global detected_markers, markers_in_sight
# markers_in_sight.clear() doesn't work. This is a Python 3.3+ command
markers_in_sight = []
n = len(msg.markers)
for i in range(n):
detected_markers.add(msg.markers[i].id)
markers_in_sight.append(msg.markers[i].id)
# print("detected_markers"+str(detected_markers))
# print(markers_in_sight)
def ar_action(markers):
human_id = 0
if human_id in markers:
print("Human found!")
def main():
global markers_in_sight
rospy.init_node('ar_pose_subscriber', anonymous=False)
rospy.Subscriber('/ar_pose_marker', AlvarMarkers, callback)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
ar_action(markers_in_sight)
rate.sleep()
if __name__ == '__main__':
main()
Note
You can download the whole ar_tutorials package with this link.