Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Python nodes don't correctly get access to mapped parameters #163

Closed
gsalinas opened this issue Dec 18, 2023 · 0 comments
Closed

Python nodes don't correctly get access to mapped parameters #163

gsalinas opened this issue Dec 18, 2023 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@gsalinas
Copy link

Hi,

I've noticed that using mapped parameters with Python nodes doesn't work correctly; the parameter will appear correct from the CLI with ros2 param get but accessing it internally in the Python node it keeps the default value, except for whichever mapped parameter is the last one declared in the YAML definitions.

An example, making minimal changes to the Python generate_parameter_module_example:

  • Add a loop to the example node init method that logs all the PID parameters of each joint, so in generate_parameter_library/example_python/generate_parameter_module_example/minimal_publisher.py you have:
from generate_parameter_module_example.admittance_parameters import (
    admittance_controller,
)

import rclpy
import rclpy.node
from operator import attrgetter


class MinimalParam(rclpy.node.Node):
    def __init__(self):
        super().__init__('admittance_controller')
        self.timer = self.create_timer(1, self.timer_callback)

        self.param_listener = admittance_controller.ParamListener(self)
        self.params = self.param_listener.get_params()
        self.get_logger().info(
            "Initial control frame parameter is: '%s'" % self.params.control.frame.id
        )
        self.get_logger().info("fixed string is: '%s'" % self.params.fixed_string)

        self.get_logger().info(
            "Original joints parameter is: '%s'" % str(self.params.joints)
        )
        for d in self.params.fixed_array:
            self.get_logger().info("value: '%s'" % str(d))

        for j in self.params.joints:
            pid = attrgetter(j)(self.params.pid)
            self.get_logger().info(f"joint name: {j}")
            self.get_logger().info(f"p: {pid.p}")
            self.get_logger().info(f"i: {pid.i}")
            self.get_logger().info(f"d: {pid.d}")

Then, do:
ros2 run generate_parameter_module_example test_node --ros-args --params-file src/generate_parameter_library/example_python/config/implementation.yaml
and you'll get:

[INFO] [1702931911.835893981] [admittance_controller]: Initial control frame parameter is: 'ee_link'
[INFO] [1702931911.836052933] [admittance_controller]: fixed string is: 'string_value'
[INFO] [1702931911.836172245] [admittance_controller]: Original joints parameter is: '['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']'
[INFO] [1702931911.836287117] [admittance_controller]: value: '1.0'
[INFO] [1702931911.836401146] [admittance_controller]: value: '2.3'
[INFO] [1702931911.836513474] [admittance_controller]: value: '4.0'
[INFO] [1702931911.836625501] [admittance_controller]: value: '5.4'
[INFO] [1702931911.836738616] [admittance_controller]: value: '3.3'
[INFO] [1702931911.836853144] [admittance_controller]: joint name: shoulder_pan_joint
[INFO] [1702931911.836967358] [admittance_controller]: p: 1.0
[INFO] [1702931911.837081377] [admittance_controller]: i: 1.0
[INFO] [1702931911.837192002] [admittance_controller]: d: 1.0
[INFO] [1702931911.837303003] [admittance_controller]: joint name: shoulder_lift_joint
[INFO] [1702931911.837414760] [admittance_controller]: p: 1.0
[INFO] [1702931911.837524798] [admittance_controller]: i: 1.0
[INFO] [1702931911.837639334] [admittance_controller]: d: 1.0
[INFO] [1702931911.837753867] [admittance_controller]: joint name: elbow_joint
[INFO] [1702931911.837865765] [admittance_controller]: p: 1.0
[INFO] [1702931911.837976068] [admittance_controller]: i: 1.0
[INFO] [1702931911.838086412] [admittance_controller]: d: 1.0
[INFO] [1702931911.838198018] [admittance_controller]: joint name: wrist_1_joint
[INFO] [1702931911.838308879] [admittance_controller]: p: 1.0
[INFO] [1702931911.838420346] [admittance_controller]: i: 1.0
[INFO] [1702931911.838531000] [admittance_controller]: d: 1.0
[INFO] [1702931911.838642487] [admittance_controller]: joint name: wrist_2_joint
[INFO] [1702931911.838755737] [admittance_controller]: p: 1.0
[INFO] [1702931911.838880961] [admittance_controller]: i: 1.0
[INFO] [1702931911.839004642] [admittance_controller]: d: 1.0
[INFO] [1702931911.839129769] [admittance_controller]: joint name: wrist_3_joint
[INFO] [1702931911.839243073] [admittance_controller]: p: 1.0
[INFO] [1702931911.839352645] [admittance_controller]: i: 1.0
[INFO] [1702931911.839462865] [admittance_controller]: d: 1.0

Notice that the PID parameters are all 1.0, the default value, instead of the

    pid:
      shoulder_pan_joint:
        i: 0.7
      shoulder_lift_joint:
        i: 0.5
      elbow_joint:
        i: 0.2
      wrist_1_joint:
        i: 1.2
      wrist_2_joint:
        i: 0.8
      wrist_3_joint:
        i: 0.5

as defined in implementation.yaml.

Then, if you add a P term and D term to the above, so that you have:

    pid:
      shoulder_pan_joint:
        p: 123.0
        i: 0.7
        d: 987654321.0
      shoulder_lift_joint:
        i: 0.5
      elbow_joint:
        i: 0.2
      wrist_1_joint:
        i: 1.2
      wrist_2_joint:
        i: 0.8
      wrist_3_joint:
        i: 0.5

then rebuild and run again, you'll get:

[INFO] [1702932138.335568755] [admittance_controller]: Initial control frame parameter is: 'ee_link'
[INFO] [1702932138.335724239] [admittance_controller]: fixed string is: 'string_value'
[INFO] [1702932138.335842999] [admittance_controller]: Original joints parameter is: '['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']'
[INFO] [1702932138.335959293] [admittance_controller]: value: '1.0'
[INFO] [1702932138.336071713] [admittance_controller]: value: '2.3'
[INFO] [1702932138.336182861] [admittance_controller]: value: '4.0'
[INFO] [1702932138.336291746] [admittance_controller]: value: '5.4'
[INFO] [1702932138.336402207] [admittance_controller]: value: '3.3'
[INFO] [1702932138.336518224] [admittance_controller]: joint name: shoulder_pan_joint
[INFO] [1702932138.336632382] [admittance_controller]: p: 1.0
[INFO] [1702932138.336744043] [admittance_controller]: i: 1.0
[INFO] [1702932138.336854445] [admittance_controller]: d: 987654321.0
[INFO] [1702932138.336967722] [admittance_controller]: joint name: shoulder_lift_joint
[INFO] [1702932138.337078992] [admittance_controller]: p: 1.0
[INFO] [1702932138.337189974] [admittance_controller]: i: 1.0
[INFO] [1702932138.337300204] [admittance_controller]: d: 1.0
[INFO] [1702932138.337411387] [admittance_controller]: joint name: elbow_joint
[INFO] [1702932138.337520181] [admittance_controller]: p: 1.0
[INFO] [1702932138.337630019] [admittance_controller]: i: 1.0
[INFO] [1702932138.337738806] [admittance_controller]: d: 1.0
[INFO] [1702932138.337849324] [admittance_controller]: joint name: wrist_1_joint
[INFO] [1702932138.337960578] [admittance_controller]: p: 1.0
[INFO] [1702932138.338071176] [admittance_controller]: i: 1.0
[INFO] [1702932138.338180823] [admittance_controller]: d: 1.0
[INFO] [1702932138.338293346] [admittance_controller]: joint name: wrist_2_joint
[INFO] [1702932138.338403788] [admittance_controller]: p: 1.0
[INFO] [1702932138.338514715] [admittance_controller]: i: 1.0
[INFO] [1702932138.338625418] [admittance_controller]: d: 1.0
[INFO] [1702932138.338740778] [admittance_controller]: joint name: wrist_3_joint
[INFO] [1702932138.338853317] [admittance_controller]: p: 1.0
[INFO] [1702932138.338968593] [admittance_controller]: i: 1.0
[INFO] [1702932138.339077656] [admittance_controller]: d: 1.0

Note that the "d" term has gotten the value from implementation.yaml, while the "p" term and "i" term have not.

Finally, if we edit generate_parameter_library/example_python/generate_parameter_module_example/parameters.yaml, so that in the PID / map joints section, we now have:

  pid:
    rate: {
      type: double,
      default_value: 0.005,
      description: "update loop period in seconds"

    }
    __map_joints:
      i: {
        type: double,
        default_value: 1.0,
        description: "integral gain term"
      }
      d: {
        type: double,
        default_value: 1.0,
        description: "derivative gain term"
      }
      p: {
        type: double,
        default_value: 1.0,
        description: "proportional gain term",
        validation: {
          gt_eq<>: [ 0.0001 ],
        }
      }

and then rebuild and run again, we get:

[INFO] [1702932298.561139262] [admittance_controller]: Initial control frame parameter is: 'ee_link'
[INFO] [1702932298.561301753] [admittance_controller]: fixed string is: 'string_value'
[INFO] [1702932298.561421692] [admittance_controller]: Original joints parameter is: '['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']'
[INFO] [1702932298.561535857] [admittance_controller]: value: '1.0'
[INFO] [1702932298.561647588] [admittance_controller]: value: '2.3'
[INFO] [1702932298.561759031] [admittance_controller]: value: '4.0'
[INFO] [1702932298.561870210] [admittance_controller]: value: '5.4'
[INFO] [1702932298.561979382] [admittance_controller]: value: '3.3'
[INFO] [1702932298.562092621] [admittance_controller]: joint name: shoulder_pan_joint
[INFO] [1702932298.562205543] [admittance_controller]: p: 123.0
[INFO] [1702932298.562316238] [admittance_controller]: i: 1.0
[INFO] [1702932298.562424707] [admittance_controller]: d: 1.0
[INFO] [1702932298.562535437] [admittance_controller]: joint name: shoulder_lift_joint
[INFO] [1702932298.562645172] [admittance_controller]: p: 1.0
[INFO] [1702932298.562791476] [admittance_controller]: i: 1.0
[INFO] [1702932298.562906550] [admittance_controller]: d: 1.0
[INFO] [1702932298.563020253] [admittance_controller]: joint name: elbow_joint
[INFO] [1702932298.563132972] [admittance_controller]: p: 1.0
[INFO] [1702932298.563242220] [admittance_controller]: i: 1.0
[INFO] [1702932298.563351482] [admittance_controller]: d: 1.0
[INFO] [1702932298.563461369] [admittance_controller]: joint name: wrist_1_joint
[INFO] [1702932298.563572666] [admittance_controller]: p: 1.0
[INFO] [1702932298.563682169] [admittance_controller]: i: 1.0
[INFO] [1702932298.563789929] [admittance_controller]: d: 1.0
[INFO] [1702932298.563900526] [admittance_controller]: joint name: wrist_2_joint
[INFO] [1702932298.564013047] [admittance_controller]: p: 1.0
[INFO] [1702932298.564123264] [admittance_controller]: i: 1.0
[INFO] [1702932298.564231519] [admittance_controller]: d: 1.0
[INFO] [1702932298.564342966] [admittance_controller]: joint name: wrist_3_joint
[INFO] [1702932298.564453655] [admittance_controller]: p: 1.0
[INFO] [1702932298.564562240] [admittance_controller]: i: 1.0
[INFO] [1702932298.564671682] [admittance_controller]: d: 1.0

Note that now the "P" term is from (my modified) implementation.yaml and the "i" and "d" terms are the defaults.

Thank you for a great tool!

@pac48 pac48 self-assigned this Dec 31, 2023
@pac48 pac48 added the bug Something isn't working label Dec 31, 2023
@pac48 pac48 closed this as completed Jan 12, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants