Using NaN constants in message/service definitions

asked 2020-03-04 08:05:02 -0500

bjoernolav gravatar image

updated 2020-06-10 04:47:58 -0500

As part of implementing a simulator, I have a service used for resetting the simulator states named ResetState. To be able to reset only some states, I have defined a constant (float64, NaN) in the service definition which can be used to mark states which should not be reset. See the service definition:

# Service for resetting simulator states. States set to ResetState.KEEP is not reset

float64 KEEP=NaN  # Used for specifying states not to change

float64 north
float64 east
float64 heading
float64 surge_speed
float64 sway_speed
float64 yaw_rate
float64 a_1
float64 w_1
float64 a_2
float64 w_2
bool success

I am able to build the workspace just fine, but when I try to load the service in Python I get NameError: name 'nan' is not defined.

This is not surprising when looking at the generated code, which attempts to use the nan keyword without importing it (e.g. by from numpy import nan):

# This Python file uses the following encoding: utf-8
"""autogenerated by genpy from sim_milliampere/ResetStateRequest.msg. Do not edit."""
import sys
python3 = True if sys.hexversion > 0x03000000 else False
import genpy
import struct

class ResetStateRequest(genpy.Message):
  _md5sum = "42225d3d73aa534da7b187c737de1988"
  _type = "sim_milliampere/ResetStateRequest"
  _has_header = False #flag to mark the presence of a Header object
  _full_text = """

float64 KEEP=NaN

float64 north
float64 east
float64 heading
float64 surge_speed
float64 sway_speed
float64 yaw_rate
float64 a_1
float64 w_1
float64 a_2
float64 w_2
  # Pseudo-constants
  KEEP = nan

  __slots__ = ['north','east','heading','surge_speed','sway_speed','yaw_rate','a_1','w_1','a_2','w_2']
  _slot_types = ['float64','float64','float64','float64','float64','float64','float64','float64','float64','float64']

Is there a way to make catkin_make include the required import (e.g. from numpy import nan) in the generated code? I tried adding python-numpy as exec_depend and build-depend in package.xml without it solving the problem.

I'm using ROS Kinetic on Ubuntu 16.04 5.3.0-40-generic.

edit retag flag offensive close merge delete



This structure requires the user to manually set all parameters in the service request to "KEEP", otherwise the service overwrites values. If you ever extend the message, you will have to change code everywhere to avoid overwriting the new fields. It would be more maintainable and safer to keep "0" as the default parameter, and add a bitmask or boolean for each parameter when you want to force it to 0. Although with rounding errors, that may rarely be the case, anyway.

fvd gravatar image fvd  ( 2020-03-04 09:46:10 -0500 )edit

Yes, I see your point. I do, however, feels that it is a bit more explicit to let 0 be a valid value - and typically all the states will be specified. It would have been great if it was possible to set default values in the definitions, e.g. defaulting all the variables to NaN/KEEP instead of zero - only resetting them if they are explicitly specified.

bjoernolav gravatar image bjoernolav  ( 2020-03-04 10:56:01 -0500 )edit

The code generation should either alias "nan" with float('nan'): "nan = float('nan')" or use "float('nan')" in place of the symbol "nan", I guess.

glennib gravatar image glennib  ( 2020-06-10 04:43:55 -0500 )edit

Isn't the YAML syntax for a nan .NAN? This came up in an earlier Q&A: #q275681.

Haven't checked how that is retained in generated code though.

gvdhoorn gravatar image gvdhoorn  ( 2020-06-10 05:03:09 -0500 )edit

I don't think YAML is used as the language for message definitions, however it is used when generating messages with rostopic.

glennib gravatar image glennib  ( 2020-06-10 06:22:17 -0500 )edit

Seems there is an open issue on genmsg for this: ros/genmsg#85.

Without a community contribution, this is not going to be fixed it seems.

gvdhoorn gravatar image gvdhoorn  ( 2020-06-10 06:27:07 -0500 )edit

Thanks. I created a new issue at genpywhere I think it's more appropriate:

glennib gravatar image glennib  ( 2020-06-10 09:42:11 -0500 )edit