Simbody  3.6
SimTK::Force::Custom Class Reference

This class is used to define new force elements. More...

+ Inheritance diagram for SimTK::Force::Custom:

Classes

class  Implementation
 Every custom force requires implementation of a class that is derived from this abstract class. See Force::Custom for details. More...
 

Public Member Functions

 Custom (GeneralForceSubsystem &forces, Implementation *implementation)
 Create a Custom force. More...
 
 Custom ()
 Default constructor creates an empty handle. More...
 
- Public Member Functions inherited from SimTK::Force
void disable (State &) const
 Disable this force element, effectively removing it from the System for computational purposes (it is still using its ForceIndex, however). More...
 
void enable (State &) const
 Enable this force element if it was previously disabled. More...
 
bool isDisabled (const State &) const
 Test whether this force element is currently disabled in the supplied State. More...
 
void setDisabledByDefault (bool shouldBeDisabled)
 Normally force elements are enabled when defined and can be disabled later. More...
 
bool isDisabledByDefault () const
 Test whether this force element is disabled by default in which case it must be explicitly enabled before it will take effect. More...
 
void calcForceContribution (const State &state, Vector_< SpatialVec > &bodyForces, Vector_< Vec3 > &particleForces, Vector &mobilityForces) const
 Calculate the force that would be applied by this force element if the given state were realized to Dynamics stage. More...
 
Real calcPotentialEnergyContribution (const State &state) const
 Calculate the potential energy contribution that is made by this force element at the given state. More...
 
 Force ()
 Default constructor for Force handle base class does nothing. More...
 
 operator ForceIndex () const
 Implicit conversion to ForceIndex when needed. More...
 
const GeneralForceSubsystemgetForceSubsystem () const
 Get the GeneralForceSubsystem of which this Force is an element. More...
 
ForceIndex getForceIndex () const
 Get the index of this force element within its parent force subsystem. More...
 
- Public Member Functions inherited from SimTK::PIMPLHandle< Force, ForceImpl, true >
bool isEmptyHandle () const
 Returns true if this handle is empty, that is, does not refer to any implementation object. More...
 
bool isOwnerHandle () const
 Returns true if this handle is the owner of the implementation object to which it refers. More...
 
bool isSameHandle (const Force &other) const
 Determine whether the supplied handle is the same object as "this" PIMPLHandle. More...
 
void disown (Force &newOwner)
 Give up ownership of the implementation to an empty handle. More...
 
PIMPLHandlereferenceAssign (const Force &source)
 "Copy" assignment but with shallow (pointer) semantics. More...
 
PIMPLHandlecopyAssign (const Force &source)
 This is real copy assignment, with ordinary C++ object ("value") semantics. More...
 
void clearHandle ()
 Make this an empty handle, deleting the implementation object if this handle is the owner of it. More...
 
const ForceImpl & getImpl () const
 Get a const reference to the implementation associated with this Handle. More...
 
ForceImpl & updImpl ()
 Get a writable reference to the implementation associated with this Handle. More...
 
int getImplHandleCount () const
 Return the number of handles the implementation believes are referencing it. More...
 

Protected Member Functions

const ImplementationgetImplementation () const
 
ImplementationupdImplementation ()
 
- Protected Member Functions inherited from SimTK::Force
 Force (ForceImpl *r)
 Use this in a derived Force handle class constructor to supply the concrete implementation object to be stored in the handle base. More...
 
- Protected Member Functions inherited from SimTK::PIMPLHandle< Force, ForceImpl, true >
 PIMPLHandle ()
 The default constructor makes this an empty handle. More...
 
 PIMPLHandle (ForceImpl *p)
 This provides consruction of a handle referencing an existing implementation object. More...
 
 PIMPLHandle (const PIMPLHandle &source)
 The copy constructor makes either a deep (value) or shallow (reference) copy of the supplied source PIMPL object, based on whether this is a "pointer semantics" (PTR=true) or "object (value) semantics" (PTR=false, default) class. More...
 
 ~PIMPLHandle ()
 Note that the destructor is non-virtual. More...
 
PIMPLHandleoperator= (const PIMPLHandle &source)
 Copy assignment makes the current handle either a deep (value) or shallow (reference) copy of the supplied source PIMPL object, based on whether this is a "pointer sematics" (PTR=true) or "object (value) semantics" (PTR=false, default) class. More...
 
void setImpl (ForceImpl *p)
 Set the implementation for this empty handle. More...
 
bool hasSameImplementation (const Force &other) const
 Determine whether the supplied handle is a reference to the same implementation object as is referenced by "this" PIMPLHandle. More...
 

Additional Inherited Members

- Public Types inherited from SimTK::PIMPLHandle< Force, ForceImpl, true >
typedef PIMPLHandle< Force, ForceImpl, PTR > HandleBase
 
typedef HandleBase ParentHandle
 

Detailed Description

This class is used to define new force elements.

To use it, you will create a class that extends Force::Custom::Implementation. Optionally, you may also create a "handle" class extending Force::Custom that hides your implementation and provides a nicer API for users of your new force element. Here we'll use as an example a force "MySpring" that we'll presume you will declare in a header file "MySpring.h". The MySpring constructor will take a reference to a MobilizedBody mobod and a spring constant k, and connect the origin OB of body mobod to the Ground origin O by a spring of stiffness k. MySpring will apply a force of magnitude kx to OB, directed towards O, where x=|OB-O| is the current distance from OB to O. First we'll look at how MySpring would be used in a main program (whether by you or some future user of your force element), then how you would implement it.

There are two possibilities:

  • you supply only an Implementation object MySpringImpl (less work for you), or
  • you supply both the Implementation object and a handle MySpring (nicer for the user).

If you are planning only to use this force yourself, and perhaps just once for a single application, the Implementation-only approach is probably adequate. However, if you plan to have others use your new force object, it is well worth the (minimal) extra effort to provide a handle class also to make your new force behave identically to the built-in forces that come with Simbody. In either case the Implementation object is the same so you can add a handle later if you want. To reiterate: the handle class is completely optional; you must write an Implementation class but a handle class is an aesthetic addition whose main purpose is to make a cleaner API for users of your force element.

In the case where you write only the Implementation class, a user will create an instance of that class and pass it to the generic Force::Custom constructor (this would be in main.cpp or some other piece of application code):

// Using your custom force in a simulation application, no handle.
#include "Simbody.h"
#include "MySpring.h"
using namespace SimTK;
MobilizedBody mobod1 = MobilizedBody::Pin(...); // or whatever
// ...
Force::Custom spring1(forces, new MySpringImpl(mobod1,100.));

If you also write a handle class, then the API seen by the user is the same as for built-in force objects:

// Using your custom force in a simulation application, with handle.
// Same as above except last line is now:
MySpring spring1(forces, mobod1, 100.);

Writing the Implementation class

You would put the following code in MySpring.h, although you can hide it elsewhere (such as in a separate .cpp file) if you provide a handle class:

// Sample implementation of a custom force Implementation class.
class MySpringImpl: public Force::Custom::Implementation {
public:
MySpringImpl(MobilizedBody mobod, Real k)
: m_mobod(mobod), m_k(k) {}
virtual void calcForce(const State& state,
Vector_<SpatialVec>& bodyForcesInG,
Vector_<Vec3>& particleForcesInG,
Vector& mobilityForces) const
{
Vec3 bodyPointInB(0,0,0); // body origin (in the body frame)
Vec3 pos = m_mobod.getBodyOriginLocation(state); // in Ground frame
// apply force towards origin, proportional to distance x
m_mobod.applyForceToBodyPoint(state, bodyPointInB, -m_k*pos,
bodyForcesInG);
}
virtual Real calcPotentialEnergy(const State& state) const {
Vec3 pos = m_mobod.getBodyOriginLocation(state); // in Ground
Real x = pos.norm(); // distance from Ground origin
return m_k*x*x/2; // potential energy in the spring
}
private:
MobilizedBody m_mobod; // the body to which to apply the force
Real m_k; // spring stiffness
};

To write the code exactly as above, the compiler has to be told to look in the SimTK namespace for some of the symbols. There are a variety of ways to do that; see the discussion below for details.

Writing the handle class

Here is how to implement the handle class, assuming you've already written the Implementation class MySpringImpl. You would put this code (at least the declarations) in MySpring.h, following the declaration of the MySpringImpl class:

// Sample implementation of a handle class. Note: a handle class
// may *not* have any data members or virtual methods.
class MySpring : public Force::Custom {
public:
MySpring(GeneralForceSubsystem& forces, // note the "&"
MobilizedBody mobod,
Real k)
: Force::Custom(forces, new MySpringImpl(mobod,k)) {}
};

As you can see, the handle class is very simple and just hides the creation of the implementation object. Since this removes any reference to the implementation object from the user's program, it also means you can hide the implementation details completely (perhaps in a separately compiled library), which has many advantages. You can add additional methods to the handle class to provide a clean API to users of your custom force; these methods will forward to the implementation object as necessary but will not expose any aspects of the implementation that are not needed by the user.

Warning
A handle class must not have any data members or virtual methods and will not work properly if it does. Instead, store any data you need in the Implementation object.

Getting access to symbols in the SimTK namespace

The examples above glossed over the naming of symbols in the SimTK namespace. To write the code exactly as above you would need to precede it with using statements to tell the compiler to look there to resolve symbols, for example:

using namespace SimTK; // search the entire namespace for symbols, or
using SimTK::Real; using SimTK::Vector_; // define just particular symbols

Either of those approaches will work, but note that this will have the same effect on user programs that include MySpring.h as it does within the header file. That may be unwanted behavior for some users who might prefer not to have the namespace searched automatically, perhaps to avoid conflicts with their own symbols that have the same names. If you want to avoid introducing unwanted symbols into users' compilation units, then in the header file you should refer to each symbol explicitly by its full name; that is, prepend the namespace each time the symbol is used, for example:

class MySpringImpl: public SimTK::Force::Custom::Implementation {
void calcForce(const SimTK::State& state,
SimTK::Vector_<SimTK::Vec3>& particleForcesInG,
SimTK::Vector& mobilityForces) const ;
};

That is less convenient for you (and uglier) but avoids the possibility of unwanted side effects in user code so should be considered if you expect wide distribution of your new force element.

Thanks to Nur Adila Faruk Senan (a.k.a. Adila Papaya) for help in clarifying this documentation.

Constructor & Destructor Documentation

◆ Custom() [1/2]

Create a Custom force.

Parameters
forcesthe subsystem to which this force should be added
implementationthe object which implements the custom force. The Force::Custom takes over ownership of the implementation object, and deletes it when the Force itself is deleted.

◆ Custom() [2/2]

Default constructor creates an empty handle.

Member Function Documentation

◆ getImplementation()

const Implementation& SimTK::Force::Custom::getImplementation ( ) const
protected

◆ updImplementation()

Implementation& SimTK::Force::Custom::updImplementation ( )
protected

The documentation for this class was generated from the following file: