Skip to content

Subscription callback integer_value type is incorrect #1025

@PierreSachot

Description

@PierreSachot

Description
When subscribing to a parameter event in Node.js, if the data type for the parameter is set to Integer but the assigned value exceeds 9999999999999999 (15 digits), its type changes unexpectedly from 'number' to 'string'. This behavior causes the Parameter.fromParameterMessage function to fail because it expects an integer, not a string.

This issue seems to be related to the following previously reported issues:

Environment Details:

  • Library Version: 0.28.1
  • ROS Version: ROS 2 Humble
  • Platform/OS: Ubuntu 22.04

Steps To Reproduce

  1. Create a Python file with the following code to declare a parameter:
 import rclpy
  import rclpy.node
  
  class MinimalParam(rclpy.node.Node):
      def __init__(self):
          super().__init__('minimal_param_node')
  
          self.declare_parameter('my_parameter', 1000)
  
  
  def main():
      rclpy.init()
      node = MinimalParam()
      rclpy.spin(node)
  
  if __name__ == '__main__':
      main()
  1. Create the following Node.js code that subscribes to parameter events:
// Create ROS Node
const node = new Node('TestNode', '', Context.defaultContext(), options);
node.spin();

node.createSubscription(
  'rcl_interfaces/msg/ParameterEvent',
  '/parameter_events',
  { qos: QoS.profileParameterEvents },
  (buff: any) => {
    const msg = buff as ParameterEvent;


    if (msg.changed_parameters.length !== 0) {
      console.log('Received parameter event from node: ', msg.node);
      console.log('msg.value = ', msg.changed_parameters[0].value.integer_value, typeof msg.changed_parameters[0].value.integer_value);
    }
  }
  1. Start the Python node and the Node.js code in separate terminals
  2. In a third terminal, update the parameter value to 9999999999999999 using the following command:
ros2 param set /minimal_param_node my_parameter 9999999999999999

You should in Node.js terminal that the parameter integer_value type is number, next type:

  1. Now, update the parameter value to 10000000000000000 with the following command:
ros2 param set /minimal_param_node my_parameter 10000000000000000

Now, the parameter integer_value type is string


Actual Behavior
When the parameter value exceeds 9999999999999999, its data type transitions from number to string in Node.js. This type mismatch causes the Parameter.fromParameterMessage function to fail, as it expects the value to remain an integer.

A possible workaround to handle this issue could look like the following code snippet:

try {
  convertedMsg = Parameter.fromParameterMessage(msg);
  return convertedMsg;
} catch (error) {
  // get type
  const parameterType = msg.value.type;
  // handle array errors
  if (parameterType === ParameterType.INTEGER) {
    msg.value.integer_value = Number(msg.value.integer_value);
    convertedMsg = Parameter.fromParameterMessage(msg);
  }
}

This workaround allows the application to recover from the type mismatch by explicitly casting the integer_value back to a number before processing the parameter message. However, it only addresses the symptom of the issue and does not resolve the root cause.

Expected Behavior
The casting behavior (converting a string back to number when ParameterType.INTEGER is detected) should be directly detected and implemented in the fromParameterMessage function. This would eliminate the need for external type-handling workarounds and ensure consistency regardless of the parameter value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions