Ask Your Question
1

Why am I getting an rospy error in __getitem__ raise KeyError(key) ?

asked 2014-04-02 22:46:38 -0600

ct2034 gravatar image

updated 2014-04-09 05:54:50 -0600

I am trying to launch a python script and hand over a parameter from the launchfile: script:

#!/usr/bin/env python
import roslib
roslib.load_manifest( 'package_name' )

import rospy
import datetime, sys, yaml
from gazebo_msgs.msg import ModelStates

# some functions

if __name__ == '__main__':
    sim = rospy.get_param( '~sim' ) # <- edit

    rospy.init_node('package_name', anonymous=True)
    #something else ...

and I am trying to start it like that:

<?xml version="1.0"?>
<launch>
    <arg name="sim" default="true"/>

    <node name="node_name" pkg="package_name" type="script.py" output="screen">

        <param name="sim" value="$( arg sim )" />
    </node>
</launch>
edit retag flag offensive close merge delete

Comments

import roslib and roslib.load_manifest should not be used if you're using ROS Groovy or later and catkin. Not sure if the inclusion of those lines may be causing your issue.

Brendan Andrade gravatar imageBrendan Andrade ( 2014-04-03 16:39:26 -0600 )edit

I ran into this and had simply forgotten that usually I provide a default parameter:

foo = rospy.get_param( '~foo', 5.0)
lucasw gravatar imagelucasw ( 2018-07-26 09:27:49 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2014-04-09 02:10:15 -0600

ct2034 gravatar image

I know where the problem was now! I was missing the rospy.init_node() So my main should be:

if __name__ == '__main__':
    rospy.init_node('package_name', anonymous=True)
    sim = rospy.get_param( '~sim' ) # <- edit

    #something else ...
edit flag offensive delete link more

Comments

can't mark it as answered :( but it is ..

ct2034 gravatar imagect2034 ( 2014-04-09 02:24:16 -0600 )edit

It's probably a bug that trying to get params without calling init_node doesn't raise an error. @William, @Dirk Thomas?

Dan Lazewatsky gravatar imageDan Lazewatsky ( 2014-04-09 03:44:11 -0600 )edit

I'm surprised that doesn't raise an exception.

William gravatar imageWilliam ( 2014-04-09 07:28:24 -0600 )edit

The only thing I can imagine is that someone else called `rospy.init_node` in another part of the code and there for the `~` got expanded to something other than `package_name`.

William gravatar imageWilliam ( 2014-04-09 07:29:31 -0600 )edit
1

answered 2017-10-02 12:07:26 -0600

biglotusturtle gravatar image

I too had this issue but my problem was not because of rospy init.

Instead I assumed that get_param would just quietly fail if a parameter did not exist (like it does in cpp). However in python for some reason this method raises an error and kills the node if the parameter does not exist (This is a poor design IMO).

So if you're like me and have this issue, use the following:

if rospy.has_param('~sim'):
    sim = rospy.get_param('~sim')

(I realize this KEY_ERROR is documented on the rospy parameter server page, however coming from roscpp to rospy one assumes the methods behave similarly)

edit flag offensive delete link more

Comments

The API docs for rospy.get_param() say:

Raises: ...

  • KeyError - if value not set and default is not given

It doesn't "kill the node" itself, that's just default Python behaviour with uncaught exceptions.

gvdhoorn gravatar imagegvdhoorn ( 2017-10-02 12:22:17 -0600 )edit

Wrapping everything in a try: .. catch would be a way to deal with that.

re: rospy vs roscpp behaviour: yes, that is a known problem with ROS1, and is one of the reasons why in ROS2 all (official) client libraries will wrap the C client library, so we get consistent behaviour.

gvdhoorn gravatar imagegvdhoorn ( 2017-10-02 12:24:02 -0600 )edit

Agreed a try: .. catch block would achieve the same functionality but the has_param method is simpler IMO. I'm interested in this ROS2 implementation. Any info on timeline for that?

biglotusturtle gravatar imagebiglotusturtle ( 2017-10-02 12:35:42 -0600 )edit

try: .. catch is more 'pythonic' (if you care about that - ask for forgiveness and all that). Less if: ... in there.

re: ROS2: see ros2.org. Beta3 was released few weeks ago.

gvdhoorn gravatar imagegvdhoorn ( 2017-10-02 12:38:02 -0600 )edit

Thanks @gvdhoorn

biglotusturtle gravatar imagebiglotusturtle ( 2017-10-02 13:54:37 -0600 )edit
1

answered 2014-04-03 04:06:31 -0600

updated 2014-04-03 04:08:22 -0600

To get a param in the node's namespace, which is what your launchfile will create, use:

sim = rospy.get_param( '~sim' )

See getting parameters in python.

edit flag offensive delete link more

Comments

Thanks for your answer. I have actually tried this before. Then I get this exception: 20, in <module> sim = rospy.get_param( '~sim' ) File "/opt/ros/groovy/lib/python2.7/dist-packages/rospy/client.py", line 452, in get_param return _param_server[param_name] #MasterProxy does all the magic for us File "/opt/ros/groovy/lib/python2.7/dist-packages/rospy/msproxy.py", line 117, in __getitem__ raise KeyError(key) KeyError: '~sim'

ct2034 gravatar imagect2034 ( 2014-04-03 04:11:48 -0600 )edit

if you do rosparam list, does the paramater show up?

Dan Lazewatsky gravatar imageDan Lazewatsky ( 2014-04-03 05:15:14 -0600 )edit

how can i do a rosparam in this namespace? As I understand it, this param only exists in the namespace of the launchfile.

ct2034 gravatar imagect2034 ( 2014-04-08 21:56:44 -0600 )edit

And like I said, I edited my question code with the '~' as suggested above. -> same result

ct2034 gravatar imagect2034 ( 2014-04-08 21:58:20 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2014-04-02 22:46:38 -0600

Seen: 3,608 times

Last updated: Oct 02 '17