24
24
// / This example demonstrates the basic elements of creating a geometry-based
25
25
// / path using the Scholz2015GeometryPath class. The path is used to define the
26
26
// / length and speed of a PathSpring, which applies forces to the bodies of a
27
- // / double pendulum model. The path wraps around a cylindrical obstacle and
28
- // / contains a via point .
27
+ // / double pendulum model. The path contains three path points and wraps around
28
+ // / a cylindrical obstacle .
29
29
30
30
#include < OpenSim/OpenSim.h>
31
31
@@ -39,35 +39,52 @@ int main() {
39
39
// Create a PathSpring with a Scholz2015GeometryPath.
40
40
auto * spring = new PathSpring ();
41
41
spring->setName (" path_spring" );
42
- spring->setRestingLength (0.5 );
43
- spring->setDissipation (0.5 );
44
- spring->setStiffness (25 .0 );
42
+ spring->setRestingLength (0.25 );
43
+ spring->setDissipation (0.75 );
44
+ spring->setStiffness (10 .0 );
45
45
spring->set_path (Scholz2015GeometryPath ());
46
46
model.addComponent (spring);
47
47
48
- // Configure the Scholz2015GeometryPath.
48
+ // Configure the Scholz2015GeometryPath. We will update the path after
49
+ // adding it to the PathSpring, so that the Socket connections in each
50
+ // Station (i.e., path point) remain valid.
49
51
Scholz2015GeometryPath& path = spring->updPath <Scholz2015GeometryPath>();
50
52
path.setName (" path" );
51
53
52
- // The origin and insertion points are stored using the 'origin' and
53
- // 'insertion' properties of Scholz2015GeometryPath, which are of type
54
- // Station. We must update these properties after the Scholz2015GeometryPath
55
- // has been added to the PathSpring, so that the Socket connections in each
56
- // Station remain valid.
57
- path.setOrigin (model.getGround (), SimTK::Vec3 (0.05 , 0.05 , 0 .));
58
- path.setInsertion (model.getComponent <Body>(" /bodyset/b1" ),
59
- SimTK::Vec3 (-0.25 , 0.1 , 0 .));
54
+ // Add a path point connected to ground. Since this is the first path point,
55
+ // it defines the origin of the path.
56
+ path.addPathPoint (model.getGround (), SimTK::Vec3 (0.05 , 0.05 , 0 .));
60
57
61
- // Add a ContactCylinder wrapping obstacle to the path.
62
- auto * obstacle = new ContactCylinder (0.1 ,
63
- SimTK::Vec3 (-0.5 , 0.1 , 0 .), SimTK::Vec3 (0 ),
58
+ // Add a second path point, creating a straight line segment between the
59
+ // ground and body "b0".
60
+ path.addPathPoint (model.getComponent <Body>(" /bodyset/b0" ),
61
+ SimTK::Vec3 (-0.5 , 0.1 , 0 .));
62
+
63
+ // Create a ContactCylinder to use as a wrapping obstacle to the path. The
64
+ // cylinder has radius 0.15 m and is attached to body "b0".
65
+ auto * obstacle = new ContactCylinder (0.15 ,
66
+ SimTK::Vec3 (-0.2 , 0.2 , 0 .), SimTK::Vec3 (0 ),
64
67
model.getComponent <Body>(" /bodyset/b0" ));
65
68
model.addComponent (obstacle);
66
- path.addObstacle (*obstacle, SimTK::Vec3 (0 ., 0.1 , 0 .));
67
69
68
- // Add a via point to the path.
69
- path.addViaPoint (model.getComponent <Body>(" /bodyset/b1" ),
70
- SimTK::Vec3 (-0.75 , 0.1 , 0 .));
70
+ // Before we add the obstacle to the path, we must provide a "contact hint"
71
+ // to initialize the wrapping solver. The contact hint is a point on the
72
+ // surface of the obstacle, expressed in the obstacle's frame. The point
73
+ // does not have to lie on the contact geometry's surface, nor does it have
74
+ // to belong to a valid cable path. The choice of the contact hint will
75
+ // determine which side of the cylinder the path wraps around.
76
+ SimTK::Vec3 contact_hint (0 ., 0.15 , 0 .);
77
+ path.addObstacle (*obstacle, contact_hint);
78
+
79
+ // At least one path point must follow an obstacle (or list of obstacles)
80
+ // in a Scholz2015GeometryPath. Since this is the last path point we are
81
+ // adding, it defines the insertion of the path.
82
+ path.addPathPoint (model.getComponent <Body>(" /bodyset/b1" ),
83
+ SimTK::Vec3 (-0.5 , 0.1 , 0 .));
84
+
85
+ // Use the "minimum length" algorithm, which solves for a path that
86
+ // minimizes the total length of the path.
87
+ path.setAlgorithm (" MinimumLength" );
71
88
72
89
// Initialize the system.
73
90
SimTK::State state = model.initSystem ();
0 commit comments