ArUco marker detection

TIP

The following applies to image versions 0.22 and up. Older documentation is still available for for version 0.20open in new window.

TIP

Marker detection requires the camera module to be correctly plugged in and configured.

aruco_detect module detects ArUco markers and publishes their positions in ROS topics and as TF frames.

This is useful in conjunction with other positioning systems, such as GPS, Optical Flow, PX4Flow, visual odometry, ultrasonic (Marvelmindopen in new window) or UWB-based (Pozyxopen in new window) localization.

Using this module along with map-based navigation is also possible.

Setup

Set the aruco argument in ~/catkin_ws/src/clover/clover/launch/clover.launch to true:

<arg name="aruco" default="true"/>

For enabling detection set the aruco_detect argument in ~/catkin_ws/src/clover/clover/launch/aruco.launch to true:

<arg name="aruco_detect" default="true"/>

For the module to work correctly the following arguments should also be set:

<arg name="placement" default="floor"/> <!-- markers' placement, explained below  -->
<arg name="length" default="0.33"/>     <!-- length of a single marker, in meters (excluding the white border) -->

placement argument should be set to:

  • floor if all markers are on the ground;
  • ceiling if all markers are on the ceiling;
  • an empty string otherwise.

You may specify length for each marker individually by using the length_override parameter of the node aruco_detect:

<param name="length_override/3" value="0.1"/>    <!-- marker with id=3 has a side of 0.1m -->
<param name="length_override/17" value="0.25"/>  <!-- marker with id=17 has a side of 0.25m -->

Coordinate system

Each marker has its own coordinate systems. It is aligned as follows:

  • the x axis points to the right side of the marker;
  • the y axis points to the top side of the marker;
  • the z axis points outwards from the plane of the marker

Working with detected markers

Navigation within the marker-based TF frames is possible with simple_offboard node.

Sample code to fly to a point 1 metre above marker with id 5:

navigate(frame_id='aruco_5', x=0, y=0, z=1)

Sample code to fly to a point 1 metre to the left and 2 metres above marker with id 7:

navigate(frame_id='aruco_7', x=-1, y=0, z=2)

Sample code to rotate counterclockwise while hovering 1.5 metres above marker id 10:

navigate(frame_id='aruco_10', x=0, y=0, z=1.5, yaw_rate=0.5)

Note that if the required marker isn't detected for 0.5 seconds after the navigate command, the command will be ignored.

These frames may also be used in other services that accept TF frames (like get_telemetry). The following code will get the drone's position relative to the marker with id 3:

telem = get_telemetry(frame_id='aruco_3')

Note that if the required marker isn't detected for 0.5 seconds, the telem.x, telem.y, telem.z, telem.yaw fields will contain NaN.

Handling marker detection in Python

The following snippet shows how to read the aruco_detect/markers topic in Python:

import rospy
from aruco_pose.msg import MarkerArray
rospy.init_node('my_node')

# ...

def markers_callback(msg):
    print('Detected markers:'):
    for marker in msg.markers:
        print('Marker: %s' % marker)

# Create a Subscription object. Each time a message is posted in aruco_detect/markers, the markers_callback function is called with this message as its argument.
rospy.Subscriber('aruco_detect/markers', MarkerArray, markers_callback)

# ...

rospy.spin()

Each message contains the marker ID, its corner points on the image and its position relative to the camera.


Suggested reading: map-based navigation