Skip to content

Fix JSON encoding of double parameter values #903

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/core/Param.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,36 @@ export default class Param {
* @param {Object} options
* @param {Ros} options.ros - The ROSLIB.Ros connection handle.
* @param {string} options.name - The param name, like max_vel_x.
* @param {'int' | 'double'} [options.numberTypeHint] - The type hint for numbers. Defaults to 'int'.
*/
constructor(options) {
this.ros = options.ros;
this.name = options.name;
this.numberTypeHint = options.numberTypeHint ?? 'int';
}

/**
* Function to replace or transform values during JSON stringification.
*
* Stringification of a whole double value will result in a string without a decimal point.
* (e.g. 1.0 will be stringified as "1"). This causes conflict with ROS2 parameters, which incorrectly parse the incoming value as an integer.
* If dynamic typing is not enabled, this will cause the parameter set operation to fail.
*
* @param {string} _key - The key of the property being replaced (not used in the logic but needed for a replacer).
* @param {unknown} value - The value to be inspected or transformed.
* @returns {unknown} - The original value or a transformed representation of the value.
*/
replacer = (_key, value) => {
if (typeof value === 'number' && this.numberTypeHint === 'double') {
let numberStr = String(value);
if (!numberStr.includes('.')) {
numberStr += '.0';
}
return numberStr;
}
return value;
};

/**
* @callback getCallback
* @param {Object} value - The value of the param from ROS.
Expand Down Expand Up @@ -75,7 +100,7 @@ export default class Param {

var request = {
name: this.name,
value: JSON.stringify(value)
value: JSON.stringify(value, this.replacer)
};

paramClient.callService(request, callback, failedCallback);
Expand Down