ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Publishing a list, and echo its topic duplicate item problem

asked 2018-04-24 04:14:37 -0500

tolga-uni-lu gravatar image

updated 2018-04-24 05:31:38 -0500

Hello, I publish to a list by looping through recognized people on camera. Even though 2 people display action 0 and action 1 respectively, topic either says they both display 0 or 1. Do you see what is wrong with it?

My code and topic echo is below:

def callback(self, msg):
    human_list_length = len(msg.human_list)
    self.publisher_msg.num_humans = human_list_length
    self.publisher_msg.gesture_list = [GestureDetectorHuman()] * human_list_length
    rospy.loginfo("Visible humans:" + str(human_list_length))
    for human in msg.human_list:
        ind = msg.human_list.index(human)
        rospy.loginfo("Gesture from Human: " + str(ind))
        self.publisher_msg.gesture_list[ind].human_index = ind
        # Check gesture published by current human and publish respective message
        if self.hand_raise(human):
            self.publisher_msg.gesture_list[ind].gesture = str(0)
        elif self.wait_a_minute(human):
            self.publisher_msg.gesture_list[ind].gesture = str(1)

rostopic echo output:

num_humans: 2 
gesture_list: 
  - 
    human_index: 1
    gesture: "0"
  - 
    human_index: 1
    gesture: "0"
--- 
num_humans: 2 
gesture_list: 
  - 
    human_index: 1
    gesture: "1"
  - 
    human_index: 1
    gesture: "1"
--- 
num_humans: 2 
gesture_list: 
  - 
    human_index: 1
    gesture: "0"
  - 
    human_index: 1
    gesture: "0"
--- 
num_humans: 2 
gesture_list: 
  - 
    human_index: 1
    gesture: "0"
  - 
    human_index: 1
    gesture: "0"
---
edit retag flag offensive close merge delete

Comments

I don't understand how the two snippets you posted are related. The second is the Output of rostopic echo, I guess. But what about the first? Is this supposed to be the callback reacting to the data in the topic? I don't see a human_list field in the Output below. Or should this produce the ...

mgruhler gravatar image mgruhler  ( 2018-04-24 05:25:19 -0500 )edit

posted message? I'm guessing the second. But there is the question, what do the hand_raise and wait_a_minute functions do. My guess, your problem is in there.

Maybe describe in more Detail what you expect to happen where, and post the code of the publishers and relevant functions...

mgruhler gravatar image mgruhler  ( 2018-04-24 05:27:36 -0500 )edit

I can post the full code but its too long. The problem is message published is instead of adding new element inside for loop, it makes all list elements the last added element. wait_a_minute and hand_raise are the functions called they work just fine as the return is true or false.

tolga-uni-lu gravatar image tolga-uni-lu  ( 2018-04-24 05:32:43 -0500 )edit

Whoops, missed that the human_index is actually the same to. This is the crucial part!

mgruhler gravatar image mgruhler  ( 2018-04-24 05:43:05 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2018-04-24 05:41:43 -0500

mgruhler gravatar image

updated 2018-04-25 04:14:39 -0500

The Problem is in how you generate the list of objects to begin with. The * multiply will link each copy to the same instance. Thus, you Change both objects with the same call.

You should generate the list by either Clearing it and appending the appropriate newly generated GestureDetectorHuman object or use something else for generating the list, as e.g.

self.publisher_msg.gesture_list = [ GestureDetectorHuman() for _ in range(human_list_length)]

EDIT

Strange, I just tested this with a simple python class

class test(object):
    a = 0

and the behaviour is as expected.

a = [test()] * 5

creates references to the same object (i.e. changing a[0].a changes also a[1].a etc), whereas

b = [ test() for _ in range(5) ]

creates 5 objects, and changing works.

You could check by simply print a and see to which id the single elements are pointing.

Why this DOES work for simple, immutable types in python, is explained in several places. One that I like (though I'm not the python expert, and am not sure if this is the full true solution) is a comment in this StackOverflow question:

Everything is an object, and variables are names that we assign to objects (not the other way around!) So if you do a = b = c = 1; a +=1, then everything gets assigned to the object 1, and then a gets assigned to the object 2. With mutable objects like lists, dicts and sets, you can change the object itself, which will be seen by all names assigned to that object, but with ints, strings, tuples, and other immutable objects, all you can do is assign the name to a different object.

edit flag offensive delete link more

Comments

How does my way is different than List = [double] * 5. This just defines the type, buy you can change each element inside the list. I applied your way it did not work. But mistake must be somewhere there. Thank you for your answer.

tolga-uni-lu gravatar image tolga-uni-lu  ( 2018-04-24 12:04:42 -0500 )edit

see edit above

mgruhler gravatar image mgruhler  ( 2018-04-25 04:14:48 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2018-04-24 04:14:37 -0500

Seen: 413 times

Last updated: Apr 25 '18