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
205 changes: 103 additions & 102 deletions Bindings/Java/Matlab/Dynamic_Walker_Example/CreateWalkingModelAndEnvironment.m
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
%
% Copyright (c) 2005-2017 Stanford University and the Authors
% Author(s): Daniel A. Jacobs
% Contributor(s): Hannah O'Day, Chris Dembia
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
Expand All @@ -26,7 +27,7 @@
% -----------------------------------------------------------------------

% User Section - Adjust these parameters at will
outputPath = '..\Model\';
outputPath = '../Model/';
outputModelName = 'WalkerModel';

% Model Body Parameters
Expand All @@ -40,11 +41,11 @@
PelvisIZZ = 1/12*PelvisMass*PelvisWidth^2;

ThighMass = 0.05;
ThighLength = 0.5;
ThighLength = 0.40;
ThighIZZ = 1/12*ThighMass*ThighLength^2;

ShankMass = 0.05;
ShankLength = 0.5;
ShankLength = 0.435;
ShankIZZ = 1/12*ShankMass*ShankLength^2;

smallInertia = 1E-4;
Expand All @@ -65,14 +66,14 @@

% Open Model
osimModel = Model();
if(addObstacles)
if addObstacles
outputModelName = [outputModelName, 'Terrain'];
end
osimModel.setName(outputModelName);
osimModel.setAuthors('Daniel A. Jacobs, Ajay Seth');

% Get a Handle to Ground Body
ground = osimModel.getGroundBody();
ground = osimModel.getGround();

% -----------------------------------------------------------------------
% Platform
Expand All @@ -86,66 +87,54 @@
orientationInParent = Vec3(0,0,deg2rad(-10));
locationInChild = Vec3(0,0,0);
orientationInChild = Vec3(0,0,0);
platformToGround = WeldJoint('PlatformToGround', ground, locationInParent, ...
orientationInParent, platform, locationInChild, orientationInChild, false);
platformToGround = WeldJoint('PlatformToGround', ...
ground, locationInParent, orientationInParent, ...
platform, locationInChild, orientationInChild);

% Add Visible Object for GUI
platform.addDisplayGeometry('box.vtp');
platform.updDisplayer().setScaleFactors([PlatformLength, PlatformWidth, 1]);
platform.updDisplayer().translate(Vec3(PlatformLength/2-PlatformOffset,0,0));
% Add geometry to display in the GUI
platformGeomOffset = PhysicalOffsetFrame(platform, ...
Transform(Vec3(PlatformLength/2 - PlatformOffset, 0, 0)));
platformGeomOffset.attachGeometry(...
Brick(Vec3(PlatformLength, PlatformWidth, 1)));
platform.addComponent(platformGeomOffset);

% Add Body to Model
osimModel.addBody(platform);
osimModel.addJoint(platformToGround);
% -----------------------------------------------------------------------
% Create a massless body for one DOF of the Pelvis
pelvisMassless = Body();
pelvisMassless.setName('Pelvis_massless');
pelvisMassless.setMass(0);
pelvisMassless.setInertia(Inertia(0,0,0,0,0,0));

% Create Slider Joint
locationInParent = Vec3(0,PlatformWidth/2,0);
orientationInParent = Vec3(0,0,0);
locationInChild = Vec3(0,0,0);
orientationInChild = Vec3(0,0,0);
pelvisMasslessToPlatform = SliderJoint('PelvisMasslessToPlatform', platform, ...
locationInParent, orientationInParent, pelvisMassless, locationInChild, orientationInChild, false);

% Update the coordinates of the new joint
jointCoordinateSet = pelvisMasslessToPlatform.upd_CoordinateSet();
jointCoordinateSet.get(0).setRange([0, 100]);
jointCoordinateSet.get(0).setName('Pelvis_tx');
jointCoordinateSet.get(0).setDefaultValue(0);

% Add Body to Model
osimModel.addBody(pelvisMassless);
% -----------------------------------------------------------------------
% Create a massive body for the last DOF of the pelvis
% Create a massive body for the 6 DOF of the pelvis
pelvis = Body();
pelvis.setName('Pelvis');
pelvis.setMass(PelvisMass);
pelvis.setInertia(Inertia(smallInertia,PelvisIYY,smallInertia,0,0,0));

% Create a Slider Joint
locationInParent = Vec3(0,0,0);
orientationInParent = Vec3(0,0,pi/2);
locationInChild = Vec3(0,0,0);
orientationInChild = Vec3(0,0,pi/2);
pelvisToPelvisMassless = SliderJoint('PelvisToPelvisMassless', pelvisMassless, ...
locationInParent, orientationInParent, pelvis, locationInChild, orientationInChild, false);
% Create Planar Joint
pelvisToPlatform = PlanarJoint('PelvisToPlatform', platform, pelvis);

% Update the coordinates of the new joint
jointCoordinateSet = pelvisToPelvisMassless.upd_CoordinateSet();
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.

Pelvis_rz.setRange([-pi, pi]);
Pelvis_rz.setName('Pelvis_rz');
Pelvis_rz.setDefaultValue(0);

% Add Visible Object for GUI
pelvis.addDisplayGeometry('sphere.vtp');
pelvis.getDisplayer().setScaleFactors([PelvisWidth/5, PelvisWidth/5, PelvisWidth]);
Pelvis_tx = pelvisToPlatform.upd_coordinates(1);
Pelvis_tx.setRange([-10, 10]);
Pelvis_tx.setName('Pelvis_tx');
Pelvis_tx.setDefaultValue(0);

Pelvis_ty = pelvisToPlatform.upd_coordinates(2);
Pelvis_ty.setRange([-1, 2]);
Pelvis_ty.setName('Pelvis_ty');
Pelvis_ty.setDefaultValue(1.0);

% Add Body to Model
osimModel.addBody(pelvis);
osimModel.addJoint(pelvisToPlatform);

% Add geometry to display in the GUI
pelvis.attachGeometry(...
Ellipsoid(PelvisWidth/4.0, PelvisWidth/4.0, PelvisWidth/2.0));

% -----------------------------------------------------------------------
% Create the Left Thigh
leftThigh = Body();
Expand All @@ -159,20 +148,21 @@
locationInChild = Vec3(0,ThighLength/2,0);
orientationInChild = Vec3(0,0,0);
LThighToPelvis = PinJoint('LThighToPelvis', pelvis, locationInParent, ...
orientationInParent, leftThigh, locationInChild, orientationInChild, false);
orientationInParent, leftThigh, locationInChild, orientationInChild);

% Update the coordinates of the new joint
jointCoordinateSet = LThighToPelvis.upd_CoordinateSet();
jointCoordinateSet.get(0).setRange([deg2rad(-100), deg2rad(100)]);
jointCoordinateSet.get(0).setName('LHip_rz');
jointCoordinateSet.get(0).setDefaultValue(deg2rad(60));
LHip_rz = LThighToPelvis.updCoordinate();
LHip_rz.setRange([deg2rad(-100), deg2rad(100)]);
LHip_rz.setName('LHip_rz');
LHip_rz.setDefaultValue(deg2rad(-10));

% Add Visible Object for GUI
leftThigh.addDisplayGeometry('sphere.vtp');
leftThigh.getDisplayer().setScaleFactors([ThighLength/10, ThighLength, ThighLength/10]);
% Add geometry to display in the GUI
leftThigh.attachGeometry(...
Ellipsoid(ThighLength/20, ThighLength/2, ThighLength/20));

% Add Body to Model
osimModel.addBody(leftThigh);
osimModel.addJoint(LThighToPelvis);
% -----------------------------------------------------------------------
% Create the Right Thigh
rightThigh = Body();
Expand All @@ -186,20 +176,21 @@
locationInChild = Vec3(0,ThighLength/2,0);
orientationInChild = Vec3(0,0,0);
RThighToPelvis = PinJoint('RThighToPelvis', pelvis, locationInParent, ...
orientationInParent, rightThigh, locationInChild, orientationInChild, false);
orientationInParent, rightThigh, locationInChild, orientationInChild);

% Update the coordinates of the new joint
jointCoordinateSet = RThighToPelvis.upd_CoordinateSet();
jointCoordinateSet.get(0).setRange([deg2rad(-100), deg2rad(100)]);
jointCoordinateSet.get(0).setName('RHip_rz');
jointCoordinateSet.get(0).setDefaultValue(deg2rad(0));
RHip_rz = RThighToPelvis.updCoordinate();
RHip_rz.setRange([deg2rad(-100), deg2rad(100)]);
RHip_rz.setName('RHip_rz');
RHip_rz.setDefaultValue(deg2rad(30));

% Add Visible Object for GUI
rightThigh.addDisplayGeometry('sphere.vtp');
rightThigh.getDisplayer().setScaleFactors([ThighLength/10, ThighLength, ThighLength/10]);
% Add geometry to display in the GUI
rightThigh.attachGeometry(...
Ellipsoid(ThighLength/20, ThighLength/2, ThighLength/20));

% Add Body to Model
osimModel.addBody(rightThigh);
osimModel.addJoint(RThighToPelvis);
% -----------------------------------------------------------------------
% Create the Left Shank
leftShank = Body();
Expand All @@ -213,85 +204,89 @@
locationInChild = Vec3(0,ShankLength/2,0);
orientationInChild = Vec3(0,0,0);
LShankToThigh = PinJoint('LShankToLThigh', leftThigh, locationInParent, ...
orientationInParent, leftShank, locationInChild, orientationInChild, false);
orientationInParent, leftShank, locationInChild, orientationInChild);

% Update the coordinates of the new joint
jointCoordinateSet = LShankToThigh.upd_CoordinateSet();
jointCoordinateSet.get(0).setRange([deg2rad(-140), 0]);
jointCoordinateSet.get(0).setName('LKnee_rz');
jointCoordinateSet.get(0).setDefaultValue(deg2rad(0));
LKnee_rz = LShankToThigh.updCoordinate();
LKnee_rz.setRange([deg2rad(-100), 0]);
LKnee_rz.setName('LKnee_rz');
LKnee_rz.setDefaultValue(deg2rad(-30));

% Add Visible Object for GUI
leftShank.addDisplayGeometry('sphere.vtp');
leftShank.getDisplayer().setScaleFactors([ShankLength/10, ShankLength, ShankLength/10]);
% Add geometry to display in the GUI
leftShank.attachGeometry(...
Ellipsoid(ShankLength/20, ShankLength/2, ShankLength/20));

% Add Body to Model
osimModel.addBody(leftShank);
osimModel.addJoint(LShankToThigh);
% -----------------------------------------------------------------------
% Create the Right Shank
rightShank = Body();
rightShank.setName('RightShank');
rightShank.setMass(ShankMass);
rightShank.setInertia(Inertia(smallInertia,smallInertia,ShankIZZ,0,0,0));

% Rod Visuals
rightShank.addDisplayGeometry('sphere.vtp');
rightShank.getDisplayer().setScaleFactors([ShankLength/10, ShankLength, ShankLength/10]);
% Add geometry to display in the GUI
rightShank.attachGeometry(...
Ellipsoid(ShankLength/20, ShankLength/2, ShankLength/20));

% Create a Pin joint
locationInParent = Vec3(0,-ThighLength/2,0);
orientationInParent = Vec3(0,0,0);
locationInChild = Vec3(0,ShankLength/2,0);
orientationInChild = Vec3(0,0,0);
RShankToThigh = PinJoint('RShankToRThigh', rightThigh, locationInParent, orientationInParent, rightShank, locationInChild, orientationInChild, false);
RShankToThigh = PinJoint('RShankToRThigh', ...
rightThigh, locationInParent, orientationInParent, ...
rightShank, locationInChild, orientationInChild);

% Update the coordinates of the new joint
jointCoordinateSet = RShankToThigh.upd_CoordinateSet();
jointCoordinateSet.get(0).setRange([deg2rad(-140, 0]);
jointCoordinateSet.get(0).setName('RKnee_rz');
jointCoordinateSet.get(0).setDefaultValue(deg2rad(0));
RKnee_rz = RShankToThigh.updCoordinate();
RKnee_rz.setRange([deg2rad(-100), 0]);
RKnee_rz.setName('RKnee_rz');
RKnee_rz.setDefaultValue(deg2rad(-30));

% Add Body to Model
osimModel.addBody(rightShank);
osimModel.addJoint(RShankToThigh);
% -----------------------------------------------------------------------
% Add Contact Elements to the Shank and Pelvis
footSphereRadius = 0.05;

LeftFootContactSphere = ContactSphere(footSphereRadius, Vec3(0,-ShankLength/2+footSphereRadius,0), leftShank);
LeftFootContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,-ShankLength/2+footSphereRadius,0), leftShank);
LeftFootContactSphere.setName('LFootContact');
LeftFootContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(LeftFootContactSphere);

RightFootContactSphere = ContactSphere(footSphereRadius, Vec3(0,-ShankLength/2+footSphereRadius,0), rightShank);
RightFootContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,-ShankLength/2+footSphereRadius,0), rightShank);
RightFootContactSphere.setName('RFootContact');
RightFootContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(RightFootContactSphere);

LeftKneeContactSphere = ContactSphere(footSphereRadius, Vec3(0,ShankLength/2,0), leftShank);
LeftKneeContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,ShankLength/2,0), leftShank);
LeftKneeContactSphere.setName('LKneeContact');
LeftKneeContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(LeftKneeContactSphere);

RightKneeContactSphere = ContactSphere(footSphereRadius, Vec3(0,ShankLength/2,0), rightShank);
RightKneeContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,ShankLength/2,0), rightShank);
RightKneeContactSphere.setName('RKneeContact');
RightKneeContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(RightKneeContactSphere);

LeftPelvisContactSphere = ContactSphere(footSphereRadius, Vec3(0,0,-PelvisWidth/2), pelvis);
LeftPelvisContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,0,-PelvisWidth/2), pelvis);
LeftPelvisContactSphere.setName('LHipContact');
LeftPelvisContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(LeftPelvisContactSphere);

RightPelvisContactSphere = ContactSphere(footSphereRadius, Vec3(0,0,PelvisWidth/2), pelvis);
RightPelvisContactSphere = ContactSphere(footSphereRadius, ...
Vec3(0,0,PelvisWidth/2), pelvis);
RightPelvisContactSphere.setName('RHipContact');
RightPelvisContactSphere.setDisplayPreference(4);
osimModel.addContactGeometry(RightPelvisContactSphere);

groundContactLoc = Vec3(0,PlatformWidth/2,0);
groundContactOri = Vec3(0,0,-pi/2);
groundContactSpace = ContactHalfSpace (groundContactLoc, groundContactOri, platform);
groundContactSpace = ...
ContactHalfSpace(groundContactLoc, groundContactOri, platform);
groundContactSpace.setName('PlatformContact');
groundContactSpace.setDisplayPreference(4);
osimModel.addContactGeometry(groundContactSpace);
% -----------------------------------------------------------------------
% Add Hunt Crossley Forces
Expand Down Expand Up @@ -416,24 +411,28 @@
hipUpperLimit = 100;
hipLowerLimit = -100;

LKneeLimitTorque = CoordinateLimitForce('LKnee_rz', kneeUpperLimit, upperStiffness, kneeLowerLimit, lowerStiffness, damping, transition);
LKneeLimitTorque = CoordinateLimitForce('LKnee_rz', kneeUpperLimit, ...
upperStiffness, kneeLowerLimit, lowerStiffness, damping, transition);
LKneeLimitTorque.setName('LKneeLimitTorque');
osimModel.addForce(LKneeLimitTorque);

RKneeLimitTorque = CoordinateLimitForce('RKnee_rz', kneeUpperLimit, upperStiffness, kneeLowerLimit, lowerStiffness, damping, transition);
RKneeLimitTorque = CoordinateLimitForce('RKnee_rz', kneeUpperLimit, ...
upperStiffness, kneeLowerLimit, lowerStiffness, damping, transition);
RKneeLimitTorque.setName('RKneeLimitTorque');
osimModel.addForce(RKneeLimitTorque);

LHipLimitTorque = CoordinateLimitForce('LHip_rz', hipUpperLimit, upperStiffness, hipLowerLimit, lowerStiffness, damping, transition);
LHipLimitTorque = CoordinateLimitForce('LHip_rz', hipUpperLimit, ...
upperStiffness, hipLowerLimit, lowerStiffness, damping, transition);
LHipLimitTorque.setName('LHipLimitTorque');
osimModel.addForce(LHipLimitTorque);

RHipLimitTorque = CoordinateLimitForce('RHip_rz', hipUpperLimit, upperStiffness, hipLowerLimit, lowerStiffness, damping, transition);
RHipLimitTorque = CoordinateLimitForce('RHip_rz', hipUpperLimit, ...
upperStiffness, hipLowerLimit, lowerStiffness, damping, transition);
RHipLimitTorque.setName('RHipLimitTorque');
osimModel.addForce(RHipLimitTorque);
% -----------------------------------------------------------------------
% Create Hunt Crossley Obstacle Forces
if(addObstacles)
if addObstacles
ObstacleForces = HuntCrossleyForce();
ObstacleForces.setName('ObstacleForces');
ObstacleForces.setStiffness(stiffness);
Expand All @@ -448,7 +447,7 @@
% Add Spheres
% This way of setting the seed was added in Matlab2011a as an error fix.
% Do not use the older versions to set the seed and state in rand or randn.
if(exist('rng', 'file'))
if exist('rng', 'file')
rng(0, 'twister');
else
warning('CreateWalkingModelAndEnvironment:RNG', ...
Expand All @@ -475,5 +474,7 @@

end
% -----------------------------------------------------------------------
% Ensure there are no errors with how the model was built.
osimModel.initSystem();
osimModel.print([outputPath, outputModelName, '.osim']);
display(['Model ' outputModelName ',printed']);
display(['Model ' outputModelName ', printed!']);
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ New Classes
- The WeldConstraint and BushingForces (BushingForce, CoupledBushingForce, FunctionBasedBushingForce, and ExpressionBasedBushingForce) were similarly unified (like Joints) to handle the two Frames that these classes require to operate. A LinkTwoFrames intermediate class was introduced to house the common operations. Convenience constructors for WeldConstraint and BushingFrames were affected and now require the name of the Component as the first argument. (PR #649)
- The new StatesTrajectory class allows users to load an exact representation of previously-computed states from a file. (PR #730)
- Added Point as a new base class for all points, which include: Station, Marker, and PathPoints

- Added OutputReporter as an Analysis so that users can use the existing AnalyzeTool and ForwardTool to extract Output values of interest, without modifications to the GUI. (PR #1991)

Removed Classes
Expand Down Expand Up @@ -208,6 +209,8 @@ programmatically in MATLAB or python.
- Any class derived from ModelComponent can now add its own implementation of
`extendPreScale()`, `extendScale()`, and/or `extendPostScale()` to control how
its properties are updated during scaling. (PR #1994)
- The source code for the "From the Ground Up: Building a Passive Dynamic
Walker Example" was added to this repository.

Documentation
--------------
Expand Down
Loading