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

Add BuildDynamicWalker C++ example. #2073

Merged
merged 13 commits into from
Mar 7, 2018
Merged

Add BuildDynamicWalker C++ example. #2073

merged 13 commits into from
Mar 7, 2018

Conversation

chrisdembia
Copy link
Member

This PR is part of #1775.

Brief summary of changes

  • Add the source code for the "From the Ground Up" example to the GitHub repository, so we can easily update it.
  • Updated the example code for 4.0.
  • The source code is tested but is not installed, to avoid giving students "the answer."

Testing I've completed

  • Built and ran the code and ensured the resulting model was correct.

Looking for feedback on...

  • Placement of files in the repository. I tried to mimic the existing structure of test and example folders for consistency, even though the split across directories is not ideal.

CHANGELOG.md (choose one)

  • updated.

@chrisdembia
Copy link
Member Author

The travis-ci/push failure can be ignored.

@chrisdembia
Copy link
Member Author

Ready for review.

Copy link
Member

@aseth1 aseth1 left a comment

Choose a reason for hiding this comment

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

One suggestion is to use a PlanarJoint to remove the clutter of accessing and defining Coordinates that are essentially unused by the example.

orientationInParent = Vec3(0.0, 0.0, 0.0);
locationInChild = Vec3(0.0, 0.0, 0.0);
orientationInChild = Vec3(0.0, 0.0, 0.0);
FreeJoint *pelvisToPlatform = new FreeJoint("PelvisToPlatform",
Copy link
Member

Choose a reason for hiding this comment

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

In interest of efficiency and also showcasing other joint types, I would advocate using a PlanarJoint especially since 4 of the 6dofs of the FreeJoint are locked.

@chrisdembia
Copy link
Member Author

Thanks @aseth1 ; I converted the FreeJoint to a PlanarJoint. Ready for review again.

@chrisdembia
Copy link
Member Author

@aseth1 I think the travis-ci/pr failure can be ignored. All the tests pass; the ❌ is because Travis couldn't upload doxygen to myosin.

Copy link
Member

@aseth1 aseth1 left a comment

Choose a reason for hiding this comment

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

LGTM. A very minor comment. Fine to merge as is.

orientationInChild = Vec3(0.0, 0.0, 0.0);
PlanarJoint *pelvisToPlatform = new PlanarJoint("PelvisToPlatform",
*platform, locationInParent, orientationInParent,
*pelvis, locationInChild, orientationInChild);
Copy link
Member

Choose a reason for hiding this comment

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

In the interest of streamlining and avoiding the creation of empty transforms, you could use this Joint constructor instead:

Joint(const std::string&    name,
          const PhysicalFrame&  parent,
          const PhysicalFrame&  child);

I think it would look a lot cleaner.

@chrisdembia
Copy link
Member Author

This PR is ready for review again.

  • I used the shorter joint constructor in one instance, but still left another "unnecessary" usage of the longer constructor for illustrative purposes (see the Confluence page).
  • I added Hannah O'Day's updates to CreateWalkingModelAndEnvironment.m, with some of my own changes.

Copy link
Member

@aseth1 aseth1 left a comment

Choose a reason for hiding this comment

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

Minor comments regarding naming of Coordinate variables. Happy to see it get merged either way.

jointCoordinateSet.get(0).setRange([0, 5]);
jointCoordinateSet.get(0).setName('Pelvis_ty');
jointCoordinateSet.get(0).setDefaultValue(1.0);
Pelvis_rz = pelvisToPlatform.upd_coordinates(0);
Copy link
Member

Choose a reason for hiding this comment

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

It seems a bit inconsistent to start using variables with capital first letter.

Copy link
Member Author

@chrisdembia chrisdembia Mar 6, 2018

Choose a reason for hiding this comment

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

I don't like the use of capital first letters for variables, but I did it to be consistent with the rest of the file and to match the string name of the coordinates (which I prefer to be all lower-case).

Copy link
Member

Choose a reason for hiding this comment

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

That's fine. I'm happy with the PR.

Vec3 orientationInParent(0.0, 0.0, 0.0);
Vec3 locationInChild(0.0, 0.0, 0.0);
Vec3 orientationInChild(0.0, 0.0, 0.0);
PinJoint *platformToGround = new PinJoint("PlatformToGround",
Copy link
Member

Choose a reason for hiding this comment

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

The MATLAB version uses a WeldJoint with the child joint frame having the 10degrees of incline. Any reason to make the incline a DOF and then constrain it?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's how the example was written. Using a DOF makes it easy to run simulations in the GUI with different inclines. Changing this would also require rewriting a good portion of the Confluence tutorial; this pin joint is used to explain coordinates, etc.

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense to leave it then.

Copy link
Member

@tkuchida tkuchida left a comment

Choose a reason for hiding this comment

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

Minor suggestions only 🐸

@@ -26,7 +27,7 @@
% -----------------------------------------------------------------------

% User Section - Adjust these parameters at will
outputPath = '..\Model\';
outputPath = './'; % TODO ./Model/';
Copy link
Member

Choose a reason for hiding this comment

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

Not sure whether this "TODO" was inserted as a note to yourself or intended for the example. Just checking.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

#include <OpenSim/OpenSim.h>
// "Use" the OpenSim and SimTK namespace to shorten type names.
// Note: Several classes appear in both namespaces and require using the
// fully-qualified class name (for example, OpenSim::Body).
Copy link
Member

Choose a reason for hiding this comment

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

This comment should be updated to explain why you avoided using namespace SimTK; on L7–10. Note that Body is not fully qualified on L43.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

// Get a reference to the ground object
const Ground& ground = osimModel.getGround();

// Define the acceleration of gravity
Copy link
Member

Choose a reason for hiding this comment

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

"of" -> "due to" (gravity itself doesn't accelerate)

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

PlanarJoint *pelvisToPlatform = new PlanarJoint("PelvisToPlatform",
*platform, *pelvis);

// A planar joint has three coordinates, in the following order:
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps an outdated comment? The order of the Coordinates is irrelevant because you're accessing them using enums rather than integers.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

return 1;
}
std::cout << "OpenSim example completed successfully" << std::endl;
// std::cout << "Press return to continue" << std::endl;
Copy link
Member

Choose a reason for hiding this comment

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

Intentionally left commented out?

Copy link
Member Author

@chrisdembia chrisdembia Mar 7, 2018

Choose a reason for hiding this comment

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

Yes, so that the tests don't time-out.

Copy link
Member

Choose a reason for hiding this comment

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

What are we assuming about the knowledge of the target audience? Possible thoughts:

  • The code was commented out because it doesn't work.
  • Uncommenting the code causes something to break.
  • The code was commented out and should have been removed.

Regardless, I recommend leaving it as it is.

Copy link
Member Author

Choose a reason for hiding this comment

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

This bit of code is useful when running command-line examples on Windows so that the command window doesn't close on you abruptly, so I left it in. In other places, we've added a way to detect if the code is being run as part of a test via an environment variable, but I decided not to spend time on that this time. I agree with your final suggestion.

CACHE PATH "Top-level directory of OpenSim install.")
# This command searches for the file OpenSimConfig.cmake
# in common system directories and in OPENSIM_INSTALL_DIR.
find_package(OpenSim 4.0 REQUIRED PATHS "${OPENSIM_INSTALL_DIR}")
Copy link
Member

Choose a reason for hiding this comment

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

Might add a note stating that OpenSim versions < 4.0 will still work, but the user will simply need to provide the package location manually when they run CMake. Otherwise, the reader is left wondering whether L2 is incorrect (and might incorrectly attribute a build error to the apparent dissonance between L2 and L14).

Copy link
Member Author

Choose a reason for hiding this comment

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

L2 specifies the minimum CMake version; this line specifies the minimum OpenSim version. I'll clarify

Copy link
Member

Choose a reason for hiding this comment

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

Ah, right. Unfortunate coincidence; I read the comment, ending with "OpenSim", then read the following line of code that says "VERSION 3.2". Perhaps just remove the word "OpenSim" from the comment on L1.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

@@ -34,4 +34,9 @@ elseif()

endif()

# We do not install the BuildDynamicWalker example, because it is an assignment
# in the OpenSim class. The solution to the BuildDynamicWalker assignment is in
Copy link
Member

Choose a reason for hiding this comment

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

"assignment in the OpenSim class" – I assume you mean ME/BIOE 485, but "assignment" and "class" are ambiguous here. I would replace with something like "…because it is assigned to students as homework."

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed.

Copy link
Member Author

@chrisdembia chrisdembia left a comment

Choose a reason for hiding this comment

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

Thanks @tkuchida for catching those items. I'll push an update.

CACHE PATH "Top-level directory of OpenSim install.")
# This command searches for the file OpenSimConfig.cmake
# in common system directories and in OPENSIM_INSTALL_DIR.
find_package(OpenSim 4.0 REQUIRED PATHS "${OPENSIM_INSTALL_DIR}")
Copy link
Member Author

Choose a reason for hiding this comment

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

L2 specifies the minimum CMake version; this line specifies the minimum OpenSim version. I'll clarify

@chrisdembia
Copy link
Member Author

@tkuchida I've addressed your comments.

Copy link
Member

@tkuchida tkuchida left a comment

Choose a reason for hiding this comment

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

👍 🦎

@chrisdembia
Copy link
Member Author

Thanks @tkuchida

@tkuchida
Copy link
Member

tkuchida commented Mar 7, 2018

Travis failures are unrelated; merging.

@tkuchida tkuchida merged commit 3d85133 into master Mar 7, 2018
@tkuchida tkuchida deleted the build_dynamic_walker branch March 7, 2018 03:19
@chrisdembia
Copy link
Member Author

Thanks @tkuchida

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