How i can acces to the output of the object detection node

Hi, I am using the node object detection and i want to ask if there is any topic, which can listened other node that I share in other post: “How to move the robot to a goal”, to know if the robot find the object that I tell him to shearch. Also i want to know if is possible to know the global coordinates of the object detected base in the coordinates of the map.

Hello @Humberto_Andres_Hida, if you are using the object detection node, the following topics will be published:

/objects/marker_array
/objects/axes
/objects/point_cloud2

You can visualize these topics in Rviz. The /objects/marker_array topic is a list of objects that Stretch sees. You can use this to determine whether Stretch sees the object you’re looking for. Each object in the list will also have a pose defined with respect to the “camera_color_optical_frame” TF. You can use this to determine the coordinates of the object in the map frame by transforming the pose from the color optical frame to the map frame. Here’s the documentation on the MarkerArray message:

http://docs.ros.org/en/noetic/api/visualization_msgs/html/msg/MarkerArray.html

1 Like

I tried to subscribe to the topic with the next code code the terminal don’t show me the prints.

#!/usr/bin/env python3

import rospy
import tf
import geometry_msgs
from geometry_msgs.msg import PoseWithCovarianceStamped,Pose
from visualization_msgs.msg import Marker
from visualization_msgs.msg import MarkerArray
from geometry_msgs.msg import Point


def callback(data):
    objects_list = data.markers
    for obj in objects_list:
        print("Object ID:{}".format(obj.id))
        print("Position(x,y,z):({},{},{})".format(obj.pose.position.x,obj.pose.position.y,obj.pose.position.z))
def listener():
    rospy.init_node('obect_detection',anonymous=True)
    rospy.Subscriber('objects', MarkerArray, callback)
    rospy.spin()
if __name__ == '__main__':
    try:
        listener()
    except rospy.ROSInterruptException:
        pass

Hi i resolved the problem with the next code:

#!/usr/bin/env python3

import rospy
import tf
import geometry_msgs
from geometry_msgs.msg import PoseWithCovarianceStamped,Pose
from visualization_msgs.msg import Marker
from visualization_msgs.msg import MarkerArray
from geometry_msgs.msg import Point


def callback(data):
    objects_list = data.markers
    for obj in objects_list:
        object_name=obj.text
        print("Object:{}".format(object_name))
        print("Position(x,y,z):({},{},{})".format(obj.pose.position.x,obj.pose.position.y,obj.pose.position.z))
def listener():
    rospy.init_node('obect_detection',anonymous=True)
    rospy.Subscriber('/objects/marker_array', MarkerArray, callback)
    rospy.spin()
if __name__ == '__main__':
    try:
        listener()
    except rospy.ROSInterruptException:
        pass

i understand that obj.pose.position is the coordinates of the object taking the camera as reference and obj.text is the name of the object that is detected rigth? Then for what is the /objects/axes message?

Correct, obj.pose.position is the coordinates of the object with respect to the camera and obj.text is the YOLO class of the detected object. The “/object/axes” topic gives similar information, but is visualized in Rviz as an cartesian frame instead of the bounding box that is visualized from “/object/marker_array”. Either can be used.

i used the next code to have to name of the object and the coordinates o this taking as a reference the camera:

#!/usr/bin/env python3

import rospy
import tf
import geometry_msgs
from geometry_msgs.msg import PoseWithCovarianceStamped,Pose
from visualization_msgs.msg import Marker
from visualization_msgs.msg import MarkerArray
from geometry_msgs.msg import Point


def callback(data):
    objects_list = data.markers
    for obj in objects_list:
        object_name=obj.text
        print("Object:{}".format(object_name))
        print("Position(x,y,z):({},{},{})".format(obj.pose.position.x,obj.pose.position.y,obj.pose.position.z))
def listener():
    rospy.init_node('obect_detection',anonymous=True)
    rospy.Subscriber('/objects/marker_array', MarkerArray, callback)
    rospy.spin()
if __name__ == '__main__':
    try:
        listener()
    except rospy.ROSInterruptException:
        pass

But when i try to change the code to transform the coordinates to global coordinates don’t work, the code that i use is this:

#!/usr/bin/env python3

import rospy
import tf
import geometry_msgs
from geometry_msgs.msg import PoseWithCovarianceStamped,Pose, PoseStamped
from visualization_msgs.msg import Marker
from visualization_msgs.msg import MarkerArray
from geometry_msgs.msg import Point



def transform_to_map(obj_pose_camera, tf_listener):
    tf_listener.waitForTransform("map",obj_pose_camera.header.frame_id,rospy.Time(),rospy.Duration(1.0))
    obj_pose_map = tf_listener.transformPose("map",obj_pose_camera)
    return obj_pose_map

def callback(data,tf_listener):
    objects_list = data.markers
    for obj in objects_list:
        #Localización dle objeto en base a la camara
        obj_pose_camera =PoseStamped()
        obj_pose_camera.header.frame_id="camera_color_optical_frame"
        obj_pose_camera.pose =obj.pose
        try:
            obj_pose_map = transform_to_map(obj_pose_camera, tf_listener)
        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
            rospy.logwarn("No se pudo obtener tranformación al marco map")
            return
        object_name=obj.text
        print("Object:{}".format(object_name))
        print("Position(x,y,z):({},{},{})".format(obj_pose_map.pose.position.x,obj_pose_map.position.y,obj_pose_map.position.z))
def listener():
    rospy.init_node('obect_detection',anonymous=True)
    tf_listener = tf.TransformListener()
    rospy.Subscriber('/objects/marker_array', MarkerArray, callback,callback_args=tf_listener)
    rospy.spin()

if __name__ == '__main__':
    try:
        listener()
    except rospy.ROSInterruptException:
        pass

With this code i have the error: [ERROR] [1690905839.323746]: bad callback: <function callback at 0x7fdb2ebc6dc0>
is “camera_color_optical_frame” the name of the frame that i have to use?
Could you help mi to know what is wrong with my code or if is there a essay way to do

sorry for the messages, the code “works” but should run the launch files in the order:

  1. the launch to detect object
  2. the launch to navigate in a map

Hi @Humberto_Andres_Hida, no worries, I haven’t had a chance to run your code yet. Are you still seeing the [ERROR] [1690905839.323746]: bad callback: <function callback at 0x7fdb2ebc6dc0> error?

Hi, it’s working now correctly, but the thing of the specific order is just a temporary fix.
Thanks for always help me.

Glad to hear it, let me know if @Mohamed_Fazil’s suggestion in this post helps you create a single launch file that can run both functionality at the same time.

Sorry for the late answer, I am using the robot in a lab and i couldn’t use for a long time.
The thing is that i can modified the code of the robot because other people can use, so i am using a ROS remote master, but if i change the launch file as @Mohamed_Fazil said, in my PC, then i have a error when i try to launch the stretch_detect_object.launch.
The error is the next:
RLException: Invalid tag: environment variable ‘HELLO_FLEET_PATH’ is not set.

Arg xml is
The traceback for the exception was written to the log file

Also now if i launch the both launch files as i told you before, the robot can’t move to a goal

Hi @Humberto_Andres_Hida,
I assume you are trying to execute stretch_detect_object.launch from an external computer’s terminal. The stretch_detect_object.launch is expected to be launched only from the robot’s terminal and not from any other external computer. Even with ROS remote master setup, it only allows you to discover and communicate with the nodes running on the robot.

The debug log is saved to the robot’s path that is defined in the environment variable HELLO_FLEET_PATH. This should already be set up in your robot during the factory install.
In case your facing the same issue while executing the above launch from the robot’s terminal: To verify it, you can execute printenv | grep HELLO_FLEET_PATH in your robot’s terminal to check if this environment variable is already set.

hello, The node is working in the robot’s terminal, but the thing is that i want to execute the navigation.launch and stretch_detect_object.launch at the same time, but i i try this the robot can’t move, because only one stretch_driver node could run at an instance and I have to modified the the launch file as you told in other post.
I need to execute both file, due to I am using the robot to looking for a object in a lab base on probabilities.