Skip to content
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

Allow using NaN default values #825

Closed
wants to merge 5 commits into from

Conversation

henrygerardmoore
Copy link

@henrygerardmoore henrygerardmoore commented Sep 5, 2024

Hello, this is my first attempt at a contribution here, so please let me know if I need to change something.

Anyway, I noticed that you cannot default to NaN in .msg definitions, which could be useful, especially when NaNs are used as a sentinel value, which is somewhat common. This PR is my attempt to add this capability.

Is the docstring I added correct? The rosidl_generator_cpp primitive_value_to_cpp function says that the type of value is a python builtin, but when I tried isnan in rosidl_generator_c it didn't work, while == 'nan' did. I'm not sure how to test rosidl_generator_cpp so I would appreciate a double check or someone telling me how to test it.

Oh also, I tried adding a bogus message in the .msg file (float32 FLOAT32_FAKE=test) to make sure it wouldn't just convert to NaN, and it didn't. Just failed to build, as you would expect.

Signed-off-by: Henry Moore <[email protected]>
Copy link

@fujitatomoya fujitatomoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a replacement of #789.

@Ryanf55 since you are the original author for #789, if you can review this, that would be really appreciated.

Copy link

@fujitatomoya fujitatomoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@henrygerardmoore thank you for the PR.

IMO we can revise #789 or borrow some fixes from there? what do you think?

rosidl_generator_c/rosidl_generator_c/__init__.py Outdated Show resolved Hide resolved
rosidl_generator_cpp/resource/idl__struct.hpp.em Outdated Show resolved Hide resolved
Signed-off-by: Henry Moore <[email protected]>
@henrygerardmoore
Copy link
Author

@fujitatomoya Thank you for the review! Apologies that I didn't see #789 before making this, I should've checked for similar existing PRs. I have applied your suggestions, they both made sense and seemed correct to me.

@Ryanf55
Copy link

Ryanf55 commented Sep 6, 2024

this is a replacement of #789.

@Ryanf55 since you are the original author for #789, if you can review this, that would be really appreciated.

yea, compared to my PR, it's very similar - looks good.
We've been using a variation of my branch internally for months in both python and C++, so I'll make sure my upstream is synced.
I'd like to combine the best of both PR's.

I never got an answer from the ROS maintainers on how they want to handle equality of messages that contain NaN fields. The lack of consenses is what held me up spending more time on this.

@henrygerardmoore
Copy link
Author

@Ryanf55 thank you for taking a look! I can close this PR now that I am aware of yours.

@@ -209,9 +222,13 @@ def basic_value_to_c(type_, value):
return f'{value}ull'

if 'float' == type_.typename:
if isnan(float(value)):
return 'NAN'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to use 'nanf(\"\")' on my PR to avoid the c-style cast to a double later.

@[ end if]@
@[ elif constant.type.typename == 'double']@
@[ if constant.value == 'nan']
std::numeric_limits<double>::quiet_NaN()@
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of coding this, I chose to use the primitive_value_to_cpp function to promote reuse.

'octet',
'int8', 'uint8',
'int16', 'uint16',
]:
return str(value)

if type_.typename in ['double', 'long double']:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also checked if it was a float here.

'octet',
'int8', 'uint8',
'int16', 'uint16',
]:
return str(value)

if type_.typename in ['double', 'long double']:
if isnan(value):
return 'std::numeric_limits<double>::quiet_NaN()'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hard-coding as double, I used the type name here.

'octet',
'int8', 'uint8',
'int16', 'uint16',
]:
return str(value)

if type_.typename in ['double', 'long double']:
if isnan(value):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, I needed to surroudn value in a float() cast otherwise it threw.

@Ryanf55
Copy link

Ryanf55 commented Sep 6, 2024

@Ryanf55 thank you for taking a look! I can close this PR now that I am aware of yours.

Yea, please review mine and see if you can find any issues. A lot of the content is very similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants