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

Support printing sdf poses in degrees and allow snapping to commonly used angles #689

Merged
merged 60 commits into from
Dec 21, 2021

Conversation

aaronchongth
Copy link
Collaborator

@aaronchongth aaronchongth commented Sep 7, 2021

🎉 New feature

Related to #646

Summary

Support options in printing,

ign sdf -p PATH
ign sdf -p PATH --degrees
ign sdf -p PATH --snap-to-degrees 15
ign sdf -p PATH --snap-to-degrees 15 --snap-tolerance 0.01

snap-to-degress must be larger than 0, less than or equal to 360.

snap-tolerance must be larger than 0, less than 360, and less than snap-to-degrees.

For example,

<pose>1 2 3   0.523756 0.785555 1.0473546</pose>

Printing options,

ign sdf -p test.sdf --degrees
# <pose degrees='true' rotation_format='euler_rpy'>1 2 3   30.009 45.009 60.009</pose>

ign sdf -p test.sdf --snap-to-degrees 5
# <pose degrees='true' rotation_format='euler_rpy'>1 2 3   30 45 60</pose>

ign sdf -p test.sdf --snap-to-degrees 20
# <pose degrees='true' rotation_format='euler_rpy'>1 2 3   30.009 45.009 60</pose>

ign sdf -p test.sdf --snap-to-degrees 5 --snap-tolerance 0.008
# <pose degrees='true' rotation_format='euler_rpy'>1 2 3   30.009 45.009 60.009</pose>

ign sdf -p test.sdf --snap-to-degrees 5 --snap-tolerance 0.01
# <pose degrees='true' rotation_format='euler_rpy'>1 2 3   30 45 60</pose>

Behavior changes

Checklist

  • Signed all commits for DCO
  • Added tests
  • Added example and/or tutorial
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge

@github-actions github-actions bot added the 🏯 fortress Ignition Fortress label Sep 7, 2021
@chapulina chapulina added the beta Targeting beta release of upcoming collection label Sep 8, 2021
@chapulina chapulina removed the beta Targeting beta release of upcoming collection label Sep 20, 2021
@jennuine jennuine mentioned this pull request Sep 21, 2021
8 tasks
@azeey
Copy link
Collaborator

azeey commented Sep 21, 2021

The API changes from this PR have been captured by #708.

@aaronchongth aaronchongth changed the base branch from main to sdf12 October 4, 2021 09:57
@aaronchongth aaronchongth force-pushed the aaron/snapping-rotation-printouts branch 2 times, most recently from 2a2b58c to 983362f Compare October 10, 2021 18:07
@codecov-commenter
Copy link

codecov-commenter commented Oct 18, 2021

Codecov Report

Merging #689 (1871f32) into sdf12 (de356cd) will increase coverage by 0.13%.
The diff coverage is 98.48%.

❗ Current head 1871f32 differs from pull request most recent head 27a6148. Consider uploading reports for the commit 27a6148 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##            sdf12     #689      +/-   ##
==========================================
+ Coverage   90.57%   90.70%   +0.13%     
==========================================
  Files          78       78              
  Lines       12336    12439     +103     
==========================================
+ Hits        11173    11283     +110     
+ Misses       1163     1156       -7     
Impacted Files Coverage Δ
include/sdf/Element.hh 100.00% <ø> (ø)
include/sdf/Param.hh 78.57% <ø> (ø)
src/Param.cc 91.28% <97.05%> (+2.14%) ⬆️
src/Element.cc 96.96% <100.00%> (+0.06%) ⬆️
src/PrintConfig.cc 100.00% <100.00%> (ø)
src/ign.cc 64.15% <100.00%> (+1.77%) ⬆️
src/parser.cc 87.55% <100.00%> (+0.06%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update de356cd...27a6148. Read the comment docs.

@aaronchongth aaronchongth marked this pull request as ready for review October 20, 2021 15:04
@aaronchongth aaronchongth requested a review from azeey October 20, 2021 15:04
src/Element.cc Outdated Show resolved Hide resolved
include/sdf/Element.hh Outdated Show resolved Hide resolved
src/Param.cc Outdated Show resolved Hide resolved
src/Param.cc Outdated Show resolved Hide resolved
src/Param.cc Outdated Show resolved Hide resolved
src/ign_TEST.cc Outdated Show resolved Hide resolved
test/integration/pose_1_9_sdf.cc Outdated Show resolved Hide resolved
src/ign_TEST.cc Outdated Show resolved Hide resolved
src/ign_TEST.cc Show resolved Hide resolved
src/ign_TEST.cc Show resolved Hide resolved
@aaronchongth
Copy link
Collaborator Author

aaronchongth commented Dec 14, 2021

1400948 reverts all unnecessary changes made to old tests due to the experimental nature of handling parsing since the start of sdf12, specifically by https://github.com/ignitionrobotics/sdformat/pull/589/files

As of now, the behavior of getting strings from values will all reside in ParamPrivate::StringFromValueImpl, which

  • The default value to string process uses ParamStreamer (which gives us the old behavior)
  • bool and pose has their own type specific methods of extracting the strings

Apologies for all the back and forth regarding modifying old tests. As of 1400948 we should be good to go and no longer have to worry about changes in behavior, unless another type requires its own value-to-string method.

@aaronchongth aaronchongth requested a review from azeey December 14, 2021 16:07
Copy link
Collaborator

@azeey azeey left a comment

Choose a reason for hiding this comment

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

I was struggling to understand what ToString behavior is with floating point numbers since we are now changing behavior again. Here's what I've come up so far to summarize the current behavior.

  1. If the element is set by the user, the string value used by the user is printed verbatim when ToString is called (except for Poses whose behavior depends on the PrintConfig setting).
  2. Sometimes, if the element is set by the user, the value is read by the libsdformat and converted to a binary representation. When ToString is called, the binary representation is converted back to a string.
  3. If the element is not present, but a default element is added by libsdformat, the string value is read from the default attribute of the element's description, converted to a binary representation, and converted back to a string.

I then used the following file to test the behavior.

<sdf version="1.9">
  <world name="default">
    <model name="M1">
      <link name="L1">
        <visual name="v1">
          <material>
            <diffuse>0.15 0.6 0.8</diffuse><!-- (1) String printed verbatim. Type: color -->
            <render_order>0.15</render_order><!-- (2) Converted to binary then to string. Type: float -->
          </material>
          <transparency>0.15</transparency><!-- (2) Converted to binary then to string. Type: double -->
        </visual>
        <sensor name='camera' type='camera'>
          <pose>-1.06 0.090912 0 0 0 3.14</pose> <!-- (1) String printed verbatim. Type: pose -->
          <camera>
            <horizontal_fov>1.40</horizontal_fov> <!-- (2) Converted to binary then to string. Type: double -->
            <clip>
              <near>0.15</near><!-- (2) Converted to binary then to string. Type: double -->
            </clip>
            <distortion>
              <center>0.15 1.4</center> <!-- (1) String printed verbatim. Type: vector2 -->
            </distortion>
          </camera>
        </sensor>
      </link>
      <joint name="j1" type="revolute">
        <parent>world</parent>
        <child>L1</child>
        <axis>
          <xyz>0.12 0.34 0.56</xyz> <!-- (1) String printed verbatim. Type: vector3 -->
        </axis>
      </joint>
    </model>
    <!--<magnetig_field> (3) Default string converted to binary then to string. Type: vector3 -->
  </world>
</sdf>
Output from ign sdf -p
<sdf version='1.9'>
  <world name='default'>
    <model name='M1'>
      <link name='L1'>
        <visual name='v1'>
          <material>
            <diffuse>0.15 0.6 0.8 1</diffuse>
            <render_order>0.150000006</render_order>
          </material>
          <transparency>0.14999999999999999</transparency>
          <geometry/>
        </visual>
        <sensor name='camera' type='camera'>
          <pose>-1.06 0.090912 0 0 0 3.14</pose>
          <camera>
            <horizontal_fov>1.3999999999999999</horizontal_fov>
            <clip>
              <near>0.14999999999999999</near>
              <far>100</far>
            </clip>
            <distortion>
              <center>0.15 1.4</center>
            </distortion>
            <image>
              <width>320</width>
              <height>240</height>
            </image>
          </camera>
        </sensor>
      </link>
      <joint name='j1' type='revolute'>
        <parent>world</parent>
        <child>L1</child>
        <axis>
          <xyz>0.12 0.34 0.56</xyz>
          <limit>
            <lower>-10000000000000000</lower>
            <upper>10000000000000000</upper>
          </limit>
        </axis>
      </joint>
    </model>
    <gravity>0 0 -9.8</gravity>
    <magnetic_field>6e-06 2.3e-05 -4.2e-05</magnetic_field>
    <atmosphere type='adiabatic'/>
    <physics type='ode'>
      <max_step_size>0.001</max_step_size>
      <real_time_factor>1</real_time_factor>
      <real_time_update_rate>1000</real_time_update_rate>
    </physics>
    <scene>
      <ambient>0.4 0.4 0.4 1</ambient>
      <background>0.7 0.7 0.7 1</background>
      <shadows>true</shadows>
    </scene>
  </world>
</sdf>

My observation is the behavior is inconsistent between double types and vector* types. Would it be possible to eliminate this inconsistency?

this->GetRotationSnapTolerance() == _config.GetRotationSnapTolerance())
if (this->RotationInDegrees() == _config.RotationInDegrees() &&
this->RotationSnapToDegrees() == _config.RotationSnapToDegrees() &&
this->RotationSnapTolerance() == _config.RotationSnapTolerance())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we check for PreserveIncludes now that that's merged?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added in b541f34, thanks for spotting that!

@aaronchongth
Copy link
Collaborator Author

aaronchongth commented Dec 17, 2021

Many thanks for testing it extensively, @azeey! 🙇

I was struggling to understand what ToString behavior is with floating point numbers since we are now changing behavior again.
I apologize for the switching behavior around so often since the introduction of parsing-using-parent-element-attributes. I think a clarification question I should have asked earlier is, would we ideally like to revert all the changes made to tests/test-files back to how it was in sdf11, with only changes related to pose and bool?

This is related to #689 (comment), in order to avoid that change (returning "0"), we would need the returned string to be retrieved from parsing the binary value, instead of the string/default-string that was used to set the value. Hence 1400948.

However if we decide to keep the changes in behavior (returning string/default-string that was set), we would need the aforementioned test to return "0.0", as that was the default string value.

This will affect this observation,

If the element is set by the user, the string value used by the user is printed verbatim when ToString is called (except for Poses whose behavior depends on the PrintConfig setting).

@aaronchongth
Copy link
Collaborator Author

aaronchongth commented Dec 17, 2021

My observation is the behavior is inconsistent between double types and vector* types. Would it be possible to eliminate this inconsistency?

This is due to the different implementations of operator<< for

if we remove the template specialization for double and float, it returns

<sdf version='1.9'>
  <world name='default'>
    <model name='M1'>
      <link name='L1'>
        <visual name='v1'>
          <material>
            <diffuse>0.15 0.6 0.8</diffuse>
            <render_order>0.15</render_order>
          </material>
          <transparency>0.15</transparency>
          ...

@azeey
Copy link
Collaborator

azeey commented Dec 17, 2021

Thanks for the explanation. Eric has created #790 to address the inconsistency. I have tested this PR against all other ignition libraries and had no failures, so I'll go ahead and approve.

Copy link
Collaborator

@azeey azeey left a comment

Choose a reason for hiding this comment

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

There are a couple of unresolved conversations. Otherwise LGTM. Thanks for your patience.

@@ -131,7 +133,8 @@ extern "C" SDFORMAT_VISIBLE int cmdDescribe(const char *_version)
}

//////////////////////////////////////////////////
extern "C" SDFORMAT_VISIBLE int cmdPrint(const char *_path)
extern "C" SDFORMAT_VISIBLE int cmdPrint(const char *_path,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any thoughts?

@aaronchongth
Copy link
Collaborator Author

I noticed the recent merge for test/integration/print_config.cc, https://github.com/ignitionrobotics/sdformat/blob/sdf12/test/integration/print_config.cc#L193, where the pose is expected to have a -0 in the pitch.

Ideally we would expect the sanitization for -0 to do it's work here, however after tracing the code path, I noticed that this is due to the use of Param::SetFromString on the result of ignition::math::Pose3d::operator<<, where down the line the string was returned directly, as there were no parent element attributes or PrintConfig modifications happening.

I couldn't find any persuasive solutions to this without breaking more stuff. I would suggest we move on with the merge, however keep an eye out for the next release of ign-math so that we can utilize gazebosim/gz-math#206, and make changes to this test.

Let me know what you think.

…ng instead of default PrintConfig

Signed-off-by: Aaron Chong <[email protected]>
@scpeters
Copy link
Member

I couldn't find any persuasive solutions to this without breaking more stuff. I would suggest we move on with the merge, however keep an eye out for the next release of ign-math so that we can utilize ignitionrobotics/ign-math#206, and make changes to this test.

Let me know what you think.

that sounds good to me

@aaronchongth aaronchongth merged commit 5e91938 into sdf12 Dec 21, 2021
@aaronchongth aaronchongth deleted the aaron/snapping-rotation-printouts branch December 21, 2021 11:37
element->AddAttribute(attribute->Name(), "string", "", 1, "");
element->GetAttribute(attribute->Name())->SetFromString(
const std::string attributeName(attribute->Name());
if (attributeName == "type")
Copy link
Member

Choose a reason for hiding this comment

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

what if a plugin uses the type attribute?

we are observing some ign-gazebo test failures of the triggered_publisher test, and that plugin uses attributes with name type:

Copy link
Contributor

Choose a reason for hiding this comment

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

😄 I had just started writing a similar response here:


This broke plugins downstream on ign-gazebo. Loading a plugin like this:

    <plugin filename="ignition-gazebo-triggered-publisher-system" name="ignition::gazebo::systems::TriggeredPublisher">
      <input type="ignition.msgs.Empty" topic="/in_1"/>
      <output type="ignition.msgs.Boolean" topic="/out_1">
          data: true
      </output>
    </plugin>

Results in an assertion when the SDF is loaded:

173: Error [Param.cc:768] Unknown parameter type[ignition.msgs.Boolean]
173: Exception [Param.cc:81] SDF ASSERTION                     
173: Invalid parameter
173: In function       : Param
173: Assert expression : this->dataPtr->ValueFromStringImpl( this->dataPtr->typeName, _default, this->dataPtr->defaultValue)

I'm testing a temporary fix

Copy link
Contributor

Choose a reason for hiding this comment

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

This is what I'm trying: #809

@osrf-triage
Copy link

This pull request has been mentioned on Gazebo Community. There might be relevant details there:

https://community.gazebosim.org/t/new-ignition-releases-2022-04-13-fortress-edifice/1367/1

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

Successfully merging this pull request may close these issues.

7 participants