-
Notifications
You must be signed in to change notification settings - Fork 68
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
getParam (and getParams) not returning anything #129
Comments
Thanks for reporting this problem. The rosapi is not supported by this ROS2 bridge currently, please also see #73 |
Ok, I figured out that the ros2 bridge is trying to send the param get/set request to a rosapi node that is part of ros2-web-suite. I tried getting that working and got it running but doesnt work. However, in the process learned a thing or two about managing ROS2 parameters via the get/set_parameter service calls on each node. The ros2-web-bridge has no problem calling services so I would say this is the preferred way to manage parameters in ROS2 and no rosapi node needed! I wrote some code. I could add to Ros class and do a PR if you like. I did parameter getter/setters but didnt do param enumeration yet. export enum ParameterType {
NOT_SET=0,
BOOL=1,
INTEGER=2,
DOUBLE=3,
STRING=4,
BYTE_ARRAY=5,
BOOL_ARRAY=6,
INTEGER_ARRAY=7,
DOUBLE_ARRAY=8,
STRING_ARRAY=9,
}
export interface Parameter {
node: string;
name: string;
typeid: ParameterType;
value: any;
}
interface ServiceParameterValue {
type: number;
// "Variant" style storage of the parameter value.
bool_value?: boolean;
integer_value?: number;
double_value?: number;
string_value?: string;
byte_array_value?: number[];
bool_array_value?: boolean[];
iinteger_array_value?: number[];
double_array_value?: number[];
string_array_value?: string[];
}
interface ServiceParameter {
name: string;
value: ServiceParameterValue;
}
interface ServiceParameterResult {
successful: boolean;
reason: string;
}
export class GetParameterRequest {
ros: ROS.Ros;
node: string;
name: string | string[];
}
export class SetParameterRequest {
ros: ROS.Ros;
node: string;
params: ServiceParameter | [ServiceParameter];
}
function pull_parameter(p: ServiceParameterValue) {
switch(p.type) {
case ParameterType.NOT_SET: return null;
case ParameterType.BOOL: return p.bool_value;
case ParameterType.INTEGER: return p.integer_value;
case ParameterType.DOUBLE: return p.double_value;
case ParameterType.STRING: return p.string_value;
case ParameterType.BYTE_ARRAY: return p.byte_array_value;
case ParameterType.BOOL_ARRAY: return p.bool_array_value;
case ParameterType.INTEGER_ARRAY: return p.iinteger_array_value;
case ParameterType.DOUBLE_ARRAY: return p.double_array_value;
case ParameterType.STRING_ARRAY: return p.string_array_value;
default:
console.warn("no way to determine value from Parameter ", p);
break;
}
}
/* Get/Set METHODS
* I had these as part of a class, they could be added to the ROSLIB.Ros class.
*/
public getParameters(request: GetParameterRequest) {
let svc = new ROS.Service({
ros: request.ros,
name: request.node+'/get_parameters',
serviceType: 'rcl_interfaces/srv/GetParameters'
});
const param_names = Array.isArray(request.name)
? request.name
: [ request.name ];
let svc_request = new ROS.ServiceRequest({
names: param_names
});
return new Promise<Parameter[]>( (resolve, reject) => {
svc.callService(svc_request, response => {
if(Array.isArray(response.values)) {
// convert parameters to javascript friendly
resolve( response.values.map( (v: ServiceParameterValue, idx: number) => ({
node: request.node,
name: param_names[idx],
typeid: v.type,
value: pull_parameter(v)
} as Parameter)));
}
}, reject);
});
}
public setParameters(request: SetParameterRequest) {
let svc = new ROS.Service({
ros: request.ros,
name: request.node+'/set_parameters',
serviceType: 'rcl_interfaces/srv/SetParameters'
});
const params = Array.isArray(request.params)
? request.params
: [ request.params ];
let svc_request = new ROS.ServiceRequest({
parameters: params
});
return new Promise<ServiceParameterResult[]>( (resolve, reject) => {
svc.callService(svc_request, response => {
if(Array.isArray(response.results)) {
// convert parameters to javascript friendly
resolve( response.results as ServiceParameterResult[] );
}
}, reject);
});
} ` |
Absolutely, please submit your PR, thanks! |
Sounds good. I got param enumeration too. I will fork and integrate changes and take a week to test in my own system before submitting the PR. So give me a week's time. Thanks! I will also be doing service calls for Node Lifecycle management so I may follow up with a second PR on that one as well. |
Using Ros2 Web Bridge on ROS2 Eloquent:
I am calling getParam with a valid node name but not getting param data back. The callback is not executed. I do get plenty of subscription callbacks so the websocket and communication to ros2 web bridge is working fine. Inspecting the network tab details, I see that the request is properly going out but the web bridge is replying back with a non-descript error. You can see in this screenshot a bunch of /compliance/params subscription events (great!) but the service call to rosapi/get_param is failing with set_level "error":
I enabled debug stats in the ros2 bridge using:
DEBUG=ros2-web-bridge:Bridge node bin/rosbridge.js
...and I get this related error:
It suggests the rosapi.srv.GetParam message doesnt exist. I took a gander around the rclnodejs generated directory and I indeed can't find the message. Seems like the relevant service messages would be in generated/rcl_interfaces, yes? I see in that folder a bunch of param server and request/result messages. Grep'ing for msgname within all those generated files I get:
Did Eloquent perhaps change the Param service messages? Any other advice/suggestions?
Thank you,
Colin
The text was updated successfully, but these errors were encountered: