Ask Your Question
0

Rospy Parameter KeyError

asked 2018-10-10 10:17:44 -0600

renanmb gravatar image

updated 2018-10-10 11:43:33 -0600

jayess gravatar image

I cannot get my code to get the parameters on my config file. I just do like it is on the tutorials but it does not work and I do not understand why. I believe it might be a namespace problem with rospy. I have never had this problem with C++.

My Github with the whole code: https://github.com/renanmb/boat_pid_c...

throttle_interpolator.py

#!/usr/bin/env python
import rospy

from std_msgs.msg import Float64
from boat_controller.msg import Drive

# import some utils.
import numpy as np
import copy as copy

class InterpolateThrottle:
    def __init__(self):
        self.rpm_input_topic   = rospy.get_param('~rpm_input_topic', '/vesc/commands/motor/unsmoothed_speed')
        self.rpm_output_left_topic  = rospy.get_param('~rpm_output_left_topic', '/vesc/commands/motor/speed_left')
        self.rpm_output_right_topic  = rospy.get_param('~rpm_output_right_topic', '/vesc/commands/motor/speed_right')

        self.servo_input_topic   = rospy.get_param('~servo_input_topic', '/vesc/commands/servo/unsmoothed_position')
        self.servo_output_topic  = rospy.get_param('~servo_output_topic', '/vesc/commands/servo/position')

        self.max_rpm_acceleration = rospy.get_param('/vesc/max_rpm_acceleration')
        self.max_rpm = rospy.get_param('/vesc/vesc_driver/speed_max')
        self.min_rpm = rospy.get_param('/vesc/vesc_driver/speed_min')
        self.throttle_smoother_rate = rospy.get_param('/vesc/throttle_smoother_rate')
        self.rpm_to_erpm_gain = rospy.get_param('/vesc/rpm_to_erpm_gain')

        self.max_servo_speed = rospy.get_param('/vesc/max_servo_speed')
        self.steering_angle_to_servo_gain = rospy.get_param('/vesc/steering_angle_to_servo_gain')
        self.servo_smoother_rate = rospy.get_param('/vesc/servo_smoother_rate')
        self.max_servo = rospy.get_param('/vesc/vesc_driver/servo_max')
        self.min_servo = rospy.get_param('/vesc/vesc_driver/servo_min')

        self.last_rpm = 0
        self.desired_rpm = self.last_rpm

        self.last_servo = rospy.get_param('/vesc/steering_angle_to_servo_offset')
        self.desired_servo_position = self.last_servo

        self.rpm_output_left = rospy.Publisher(self.rpm_output_left_topic, Float64,queue_size=1)
        self.rpm_output_right = rospy.Publisher(self.rpm_output_right_topic, Float64,queue_size=1)
        self.servo_output = rospy.Publisher(self.servo_output_topic, Float64,queue_size=1)

        rospy.Subscriber(self.rpm_input_topic, Drive, self._process_throttle_command)
        rospy.Subscriber(self.servo_input_topic, Float64, self._process_servo_command)

        self.max_delta_servo = abs(self.steering_angle_to_servo_gain * self.max_servo_speed / self.servo_smoother_rate)
        rospy.Timer(rospy.Duration(1.0/self.servo_smoother_rate), self._publish_servo_command)

        self.max_delta_rpm = abs(self.rpm_to_erpm_gain * self.max_rpm_acceleration / self.throttle_smoother_rate) 

        rospy.Timer(rospy.Duration(1.0/self.max_delta_rpm), self._publish_throttle_left_command)
        rospy.Timer(rospy.Duration(1.0/self.max_delta_rpm), self._publish_throttle_right_command)

        self._run()

    def _run(self):
        rospy.spin()

    def _publish_throttle_left_command(self, evt):
        desired_delta = self.desired_rpm_left-self.last_rpm_left
        clipped_delta = max(min(desired_delta, self.max_delta_rpm), -self.max_delta_rpm)
        smoothed_rpm = self.last_rpm_left + clipped_delta
        self.last_rpm_left = smoothed_rpm
        self.rpm_output_left.publish(Float64(smoothed_rpm))

    def _publish_throttle_right_command(self, evt):
        desired_delta = self.desired_rpm_right-self.last_rpm_right
        clipped_delta = max(min(desired_delta, self.max_delta_rpm), -self.max_delta_rpm)
        smoothed_rpm = self.last_rpm_right + clipped_delta
        self.last_rpm_right = smoothed_rpm
        self.rpm_output_right.publish(Float64(smoothed_rpm))

    def _process_throttle_command(self,msg):
        input_rpm_left = msg.data
        input_rpm_right = msg.data
        input_rpm_left = min(max(input_rpm_left, self.min_rpm), self.max_rpm)
        input_rpm_right = min(max(input_rpm_right, self.min_rpm), self.max_rpm)
        self.desired_rpm_left = input_rpm_left
        self.desired_rpm_right = input_rpm_right

    def _publish_servo_command(self, evt):
        desired_delta = self.desired_servo_position-self.last_servo
        clipped_delta = max(min(desired_delta, self.max_delta_servo), -self.max_delta_servo)
        smoothed_servo = self.last_servo + clipped_delta
        self.last_servo = smoothed_servo         
        self.servo_output.publish(Float64(smoothed_servo))

    def _process_servo_command(self,msg):
        input_servo = msg.data
        input_servo = min(max(input_servo, self.min_servo), self.max_servo)
        self.desired_servo_position = input_servo


if __name__ == '__main__':
    try:
        rospy.init_node('Throttle_Interpolator')
            p = InterpolateThrottle()
        rospy.spin()
    except rospy.ROSInterruptException:
        pass

Error message:

Traceback (most recent call last):
  File "/home/renan/rostest_ws/src/boat_controller/src/throttle_interpolator.py", line 136, in <module>
    p = InterpolateThrottle()
  File "/home/renan/rostest_ws/src/boat_controller/src/throttle_interpolator.py", line 28 ...
(more)
edit retag flag offensive close merge delete

Comments

Is anybody actually loading the parameters from the yaml in the parameter server? Do you have other nodes not in the repo setting them?

If not, you could read them in?

aPonza gravatar imageaPonza ( 2018-10-10 10:46:49 -0600 )edit

My other nodes loads its parameters just fine. I tried the command rosparam load and it does not work. It says the file does not exist.

renanmb gravatar imagerenanmb ( 2018-10-10 10:57:59 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2018-10-10 11:11:35 -0600

aPonza gravatar image

updated 2018-10-12 02:42:41 -0600

Looking at the repo and your own comment it seems you might not be loading the parameters in this node / not running both nodes at the same time?

Given the file a_location.yaml containing:

foo:
  bar: [0.194717, -0.592676, 0.042564]

The python code to set a generic parameter in rospy should be:

#! /usr/bin/env python

import yaml
import rospy
import rospkg


def load_parameters():
    rospack = rospkg.RosPack()
    path_loc = rospack.get_path("a_pkg") + "/config/a_location.yaml"
    with open(path_loc, 'r') as doc:
        loc = yaml.load(doc)

    x_foo_bar = loc["foo"]["bar"][0]
    y_foo_bar = loc["foo"]["bar"][1]
    z_foo_bar = loc["foo"]["bar"][2]

    rospy.set_param("location", {'x': x_foo_bar, 'y': y_foo_bar, 'z': z_foo_bar})

    # do something


if __name__ == '__main__':
    rospy.init_node('my_node', anonymous=True)
    load_parameters()

EDIT: let's redo the example for vesc.yaml

vesc:
  max_rpm_acceleration: 0.123
#! /usr/bin/env python

import yaml
import rospy
import rospkg


def load_parameters():
    rospack = rospkg.RosPack()
    path_loc = rospack.get_path("boat_pid_controller") + "/config/vesc.yaml"
    with open(path_loc, 'r') as doc:
        parameters_vesc = yaml.load(doc)

    max_rpm_accel = parameters_vesc["vesc"]["max_rpm_acceleration"]

    rospy.set_param("max_rpm_acceleration", max_rpm_accel)


if __name__ == '__main__':
    rospy.init_node('my_node', anonymous=True)
    load_parameters()

    # now that the parameters are loaded you can use them
    p = InterpolateThrottle()
    rospy.spin()
edit flag offensive delete link more

Comments

please, I would appreciate if you could provide the source of this information, so I can study it more. To be honest I did not understand anything.

renanmb gravatar imagerenanmb ( 2018-10-10 11:16:52 -0600 )edit

I found this: http://docs.ros.org/indigo/api/rospy/...

But it is pretty much what I was trying to do.

renanmb gravatar imagerenanmb ( 2018-10-10 13:22:53 -0600 )edit

I don't understand if I answered your question. You're using kinetic, so use those docs. My source is ROS projects on github, e.g. github dot com /Salman-H/pick-place-robot/kuka_arm/scripts/target_spawn.py

aPonza gravatar imageaPonza ( 2018-10-11 02:06:33 -0600 )edit

You did not answer my question, because it still does not work.

I tried to use roslaunch to set all parameter and I created this following question on stackoverflow as well: https://stackoverflow.com/questions/5...

renanmb gravatar imagerenanmb ( 2018-10-11 10:54:25 -0600 )edit

I answered on stackexchange and edited this answer to provide an example that fits exactly your code.

aPonza gravatar imageaPonza ( 2018-10-12 02:42:01 -0600 )edit

I created this following question on stackoverflow as well

why?

gvdhoorn gravatar imagegvdhoorn ( 2018-10-12 04:47:02 -0600 )edit

It was about the launch file, this forum was giving a server error to post another question. I also tried to use the roslaunch to avoid the KeyError. Thanks for the answer. They do not cite it anywhere on the wiki. So in python I basically have to make that for every parameter.

renanmb gravatar imagerenanmb ( 2018-10-12 05:47:14 -0600 )edit
1

What @aPonza shows is one particular way to load parameters using the Python API.

But I would just use a launch file if I were you. That is much more common, better understood and more scalable.

gvdhoorn gravatar imagegvdhoorn ( 2018-10-12 05:50: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: 2018-10-10 10:17:44 -0600

Seen: 421 times

Last updated: Oct 12 '18