I’m trying to solve the part III of ROS Basics in 5 Days for Python course. In this exercise we need to create a new ROS node that contains an action server named “record_odom”. The server uses a “OdomRecord.action” message, which I defined as follows
"
geometry_msgs/Point list_of_odoms
float32 current_total
"
I believe that most of my code is done. However I’m getting an error when trying to save the odometry readings on the list_of_odoms atribute. The server callback code is´
When the success variable is set to Tue, the following error is returned
"
[ERROR] [1620687943.209565, 2469.565000]: Exception in your execute callback: ‘list’ object has no attribute ‘x’
Traceback (most recent call last):
File “/opt/ros/noetic/lib/python3/dist-packages/actionlib/simple_action_server.py”, line 289, in executeLoop
self.execute_callback(goal)
File “/home/user/catkin_ws/src/my_project/scripts/partII_actions_server.py”, line 67, in goal_callback
self._result.result.list_of_odoms.x = vec_result_x
AttributeError: ‘list’ object has no attribute ‘x’
"
I can’t tell how you’ve defined list_of_odoms, since that’s not in your code example.
Also can’t tell - did you import zeros from numpy? That’s not a regular python function. And how did you decide that 40 items would be enough? Why not just make list variables and then append items to them as you go? No need to create a bunch of list items with 0. You can actually store each odom reading in a single list, and then access the components as needed if need be.
/K
I did import the zeros from numpy. However, as you pointed out, it is better to just append the new items on the list. I’ve already changed this on my code. Anyway, this do not solve the problem.
The list_of_odoms ins defined inside the “OdomRecord.action” message which is a file inside the action folder with the following content :
Right - so list_of_odoms is really a list of Point messages. You need to specify which message in the list you’re taking the x value of. And you could be appending new odom points to that list as you take readings. Then you can just use the list and get the x,y,z components as needed rather than creating new lists.
However, as a result of the append command, all the result list is changing. In the following, it is shown the result.list_of_odoms list between two iterations
Ok, i have checked your package, seems there is a problem of referencing, to correct it you just have to make a new instance of Point, everytime you want to append a new one, so the new lines for saving the odometry readings become:
@u1802520 is correct. Look up the topic of Python assigning by value or reference. The reason you were getting copies of the same numbers is because you were changing the values the different names pointed to (I don’t know that I’m explaining it well).
I’m also still not sure why you’re bothering with the whole odom.readings.x etc. You seem to be making this harder than it needs to be. With your odom_callback just capture the odometry message. Append that to the list of odometry messages, and also get the data you want from it as needed.