How To: Tracking ArUco markers using a USB Webcam and ROS

For my research I needed to setup ROS to use ArUco so that I could track these ArUco markers placed randomly in the environment and localize my robot.

Assuming that you have your catkin workspace setup, here are the steps:

1.  $cd ~/catkin_ws/src/

2. $git clone https://github.com/pal-robotics/aruco_ros.git

3. $cd ..

4. $catkin_make install

5. $sudo apt-get install ros-indigo-usb-cam

6. $source install/setup.bash

7. $cd src/aruco_ros/aruco_ros/launch/

Now you need to modify the single.launch file so that you remap the image and camera info to the topics published by usb_cam node.

<launch>

<arg name=”markerId” default=”582″/>
<arg name=”markerSize” default=”0.034″/> <!– in m –>
<arg name=”eye” default=”left”/>
<arg name=”marker_frame” default=”aruco_marker_frame”/>
<arg name=”ref_frame” default=””/> <!– leave empty and the pose will be published wrt param parent_name –>
<node pkg=”aruco_ros” type=”single” name=”aruco_single”>
<remap from=”/camera_info” to=”/usb_cam/camera_info” />
<remap from=”/image” to=”/usb_cam/image_raw” />
<param name=”image_is_rectified” value=”True”/>
<param name=”marker_size” value=”$(arg markerSize)”/>
<param name=”marker_id” value=”$(arg markerId)”/>
<param name=”reference_frame” value=”$(arg ref_frame)”/> <!– frame in which the marker pose will be refered –>
<param name=”camera_frame” value=”stereo_gazebo_$(arg eye)_camera_optical_frame”/>
<param name=”marker_frame” value=”$(arg marker_frame)” />
</node>

</launch>

8. Open 4 terminal windows:

Terminal 1: $roscore

Terminal 2: $roslaunch usb_cam-stream.launch

First paste this into a new file named usb_cam-stream.launch:

<launch>
<node name=”usb_cam” pkg=”usb_cam” type=”usb_cam_node” output=”screen” >
<param name=”video_device” value=”/dev/video0″ />
<param name=”image_width” value=”640″ />
<param name=”image_height” value=”480″ />
<param name=”pixel_format” value=”mjpeg” />
<param name=”camera_frame_id” value=”usb_cam” />
<param name=”io_method” value=”mmap”/>
</node>
</launch>

Terminal 3:

$cd ~/catkin_ws/src/aruco_ros/aruco_ros/launch/

$roslaunch single.launch

Terminal 4: $rosrun image_view image_view image:=/aruco_single/result

17 comments

  1. Hi Saurav,

    I would like to know, after launching the single board detector, which topic should I subscribe to get the orientation and the ID of the marker.

    1. Hi Aankita,

      As far as I know, you should subscribe to: /aruco_marker_publisher/markers to detect individual landmarks.

      Exammple Code from my git repo https://github.com/sauravag/FIRM-OMPL/blob/dev/include/SpaceInformation/ROSSpaceInformation.h

      arucoSubscriber_  = nHandle_.subscribe("/aruco_marker_publisher/markers", 1, &ROSSpaceInformation::arucoListenerCallback, this);

      It may be possible that the single board detector publishes to a different topic, in that case run the detector and then run,

      $ rostopic list

      to get the list of active topics. You should see something related to aruco, once you get the name of the topic you can do,

      $ rostopic info <topic_name>

      to get information about the topic.

  2. Hi Saurav!

    I would like to know what topic, if any, I should echo to print out the pose of the marker? I tried to figure out which it was by rostopic list and rostopic info but was unable to do so.

    Cheers

    1. I used /aruco_marker_publisher/markers
      In case you don’t see any Aruco topic in your rostopic list then probably the node isn’t running correctly

  3. Hi Saurav,
    If I wanted to use 3 markers, how should I edit the double.launch file?
    I need to have 3 topics for marker positions: pose, pose2 and pose 3

    How should i do it?
    Thanks so much

    1. You should not need different topics for each marker. Aruco publishes a markerlist topic. Check that out. The markerlist is a vector of markers with their ID, pose etc.

  4. Hi; I am trying out your method but it always shows this error message.

    [aruco_single-1] process has died [pid 9092, exit code -11, cmd /home/user/catkin_ws/devel/lib/aruco_ros/single /camera_info:=/usb_cam/camera_info /image:=/usb_cam/image_raw __name:=aruco_single __log:=/home/user/.ros/log/92a97332-36ea-11e7-9d4b-b8ca3aa3d65b/aruco_single-1.log].
    log file: /home/user/.ros/log/92a97332-36ea-11e7-9d4b-b8ca3aa3d65b/aruco_single-1*.log

    Do you have any clue about it?

    Kind regards

    1. You will have to open the log file at the path shown in the error message and search that for where the error occurred. Hard to asses error source without the log file.

      1. Hi, I’m encountering a similar error to that above. It seems to be some issue with establishing a connection, but I’m having trouble solving the problem:

        [rosmaster.threadpool][ERROR] 2017-06-27 10:16:17,925: Traceback (most recent call last):
        File “/opt/ros/indigo/lib/python2.7/dist-packages/rosmaster/threadpool.py”, line 218, in run
        result = cmd(*args)
        File “/opt/ros/indigo/lib/python2.7/dist-packages/rosmaster/master_api.py”, line 208, in publisher_update_task
        xmlrpcapi(api).publisherUpdate(‘/master’, topic, pub_uris)
        File “/usr/lib/python2.7/xmlrpclib.py”, line 1233, in __call__
        return self.__send(self.__name, args)
        File “/usr/lib/python2.7/xmlrpclib.py”, line 1587, in __request
        verbose=self.__verbose
        File “/usr/lib/python2.7/xmlrpclib.py”, line 1273, in request
        return self.single_request(host, handler, request_body, verbose)
        File “/usr/lib/python2.7/xmlrpclib.py”, line 1301, in single_request
        self.send_content(h, request_body)
        File “/usr/lib/python2.7/xmlrpclib.py”, line 1448, in send_content
        connection.endheaders(request_body)
        File “/usr/lib/python2.7/httplib.py”, line 1013, in endheaders
        self._send_output(message_body)
        File “/usr/lib/python2.7/httplib.py”, line 864, in _send_output
        self.send(msg)
        File “/usr/lib/python2.7/httplib.py”, line 826, in send
        self.connect()
        File “/usr/lib/python2.7/httplib.py”, line 807, in connect
        self.timeout, self.source_address)
        File “/usr/lib/python2.7/socket.py”, line 571, in create_connection
        raise err
        error: [Errno 111] Connection refused

        1. Have you set ROS_MASTER_URI or ROS_IP or ROS_HOSTNAME? You will need these to be set in order for a distributed setup to work.

          1. Here is my working environment, am I missing something?

            ROS_ROOT=/opt/ros/indigo/share/ros
            ROS_PACKAGE_PATH=/home/terra/blake_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks
            ROS_MASTER_URI=http://localhost:11311
            ROSLISP_PACKAGE_DIRECTORIES=/home/terra/blake_ws/devel/share/common-lisp
            ROS_DISTRO=indigo
            ROS_ETC_DIR=/opt/ros/indigo/etc/ros

          2. Setting ROS_IP to the local IP address results in the same error as before:

            ROS_ROOT=/opt/ros/indigo/share/ros
            ROS_PACKAGE_PATH=/home/terra/blake_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks
            ROS_MASTER_URI=http://localhost:11311
            ROSLISP_PACKAGE_DIRECTORIES=/home/terra/blake_ws/devel/share/common-lisp
            ROS_DISTRO=indigo
            ROS_IP=127.0.0.1
            ROS_ETC_DIR=/opt/ros/indigo/etc/ros

Leave a Reply

Your email address will not be published. Required fields are marked *