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

Use stringstream instead of stod to work around locale issues. #42

Merged
merged 5 commits into from
Feb 21, 2018

Conversation

clalancette
Copy link
Contributor

The URDF schema (https://github.com/ros/urdfdom/blob/master/xsd/urdf.xsd#L47) defines doubles in URDF as xs:double. Looking at the XSD document at https://www.w3.org/TR/xmlschema-2/#double, it says that the mantissa for a double is represented as a "decimal" number. And looking at the XSD document at https://www.w3.org/TR/xmlschema-2/#decimal, a decimal number is a "finite-length sequence of decimal digits (#x30-#x39) separated by a period as a decimal indicator". Thus, the locale should have no effect on how the document is parsed, and using std::stod is incorrect. This patch switches the Vector3 class to using the stream operator, which seems to ignore locale.

fixes #41

Signed-off-by: Chris Lalancette [email protected]

@traversaro
Copy link
Contributor

This patch switches the Vector3 class to using the stream operator, which seems to ignore locale.

If I understood correctly the C++ documentation, the stringstream default locale is not affected by calls to the C-style std::setlocale function (the one called by Qt, that is actually exposing the std::stod problem). However, it is affected by calls to std::locale::global, so a call to this global function in any part of the thread or the process (this is implementation defined) could still cause a failure in the URDF parser. Adding a call to the imbue method:

ss.imbue(std::locale::classic());

should avoid this problem (see robotology/idyntree#288 (comment)).

@clalancette
Copy link
Contributor Author

Adding a call to the imbue method:

Thanks for that. Done in 678ab93

This will be useful elsewhere (i.e. urdfdom).

Signed-off-by: Chris Lalancette <[email protected]>
@gavanderhoorn
Copy link

@clalancette: minor, but none of the three commits seem to have been made using your gh registered email, so they are not attributed to your account.

@clalancette
Copy link
Contributor Author

@clalancette: minor, but none of the three commits seem to have been made using your gh registered email, so they are not attributed to your account.

Ah, thanks. When we got the new "@openrobotics.org" domain, I updated my .gitconfig, but I had forgotten to verify with GitHub. Done now.

Copy link
Contributor

@sloretz sloretz left a comment

Choose a reason for hiding this comment

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

Looks good with a few includes. Think it's worth adding a test to this package?

// thrown.
static inline double strToDouble(const char *in)
{
std::stringstream ss;
Copy link
Contributor

Choose a reason for hiding this comment

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

#include <sstream>?

static inline double strToDouble(const char *in)
{
std::stringstream ss;
ss.imbue(std::locale::classic());
Copy link
Contributor

Choose a reason for hiding this comment

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

#include <locale>?

ss >> out;

if (ss.fail() || !ss.eof()) {
throw std::runtime_error("");
Copy link
Contributor

Choose a reason for hiding this comment

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

#include <stdexcept> ?

Signed-off-by: Chris Lalancette <[email protected]>
@clalancette
Copy link
Contributor Author

I've fixed up all of the includes in caf2e8c. As far as testing goes, the only thing is that there is no test infrastructure in here. I could see about adding it (gtest or similar), but then this will grow into a much larger PR. I'm inclined to kick that to another PR, but I'll let you make the final decision.

@traversaro
Copy link
Contributor

As far as testing goes, the only thing is that there is no test infrastructure in here. I could see about adding it (gtest or similar), but then this will grow into a much larger PR. I'm inclined to kick that to another PR, but I'll let you make the final decision.

I am totally not a fan of the situation, but historically tests of urdfdom_headers were added in the urdfdom repo, see ros/urdfdom#67 (comment) .

@clalancette
Copy link
Contributor Author

@traversaro Thanks a lot for the pointer. I'll go ahead and add some tests over there.

@clalancette
Copy link
Contributor Author

@scpeters Gentle ping; this PR (and the related ros/urdfdom#109) are ready for review and merging, and I'd like to get them in before Melodic. Thanks!

// for parsing, as that matches up with what the XSD for double specifies.
// On success, the double is returned; on failure, a std::runtime_error is
// thrown.
static inline double strToDouble(const char *in)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use const char * instead of const std::string &? Just curious, not asking you to change it, just hoping to learn something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a good (but sneaky) reason for it. I'm hoping that once we get this basic support in, we can use this more generally throughout the urdfdom libraries to avoid this problem. As one example, https://github.com/ros/urdfdom/blob/master/urdf_parser/src/link.cpp#L120 probably suffers from a similar problem (as do several other std::stod conversions in there). Several of those get a const char * from tinyxml, so I figured this interface was more generic rather than having to wrap those inside strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, right, I forgot I also did another PR to actually fix all of that as well: ros/urdfdom#105

@clalancette clalancette merged commit e7e0972 into master Feb 21, 2018
@clalancette clalancette deleted the stream-vector branch February 21, 2018 20:16
m-elwin added a commit to m-elwin/ros2_documentation that referenced this pull request Oct 3, 2022
I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary
clalancette pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary
mergify bot pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)
mergify bot pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)
mergify bot pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)
clalancette pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
… (#3072)

I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)

Co-authored-by: Matthew Elwin <[email protected]>
clalancette pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
… (#3073)

I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)

Co-authored-by: Matthew Elwin <[email protected]>
clalancette pushed a commit to ros2/ros2_documentation that referenced this pull request Oct 3, 2022
… (#3074)

I believe the bug with respect to locale was fixed a while back ros/urdfdom_headers#42 so setting LC_NUMERIC is no longer necessary

(cherry picked from commit 611f948)

Co-authored-by: Matthew Elwin <[email protected]>
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.

Parsing floats in URDF yields wrong value depending on locale
5 participants