Simbody
|
00001 #ifndef SimTK_SIMBODY_CONSTRAINT_H_ 00002 #define SimTK_SIMBODY_CONSTRAINT_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simbody(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2007-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00045 #include "SimTKmath.h" 00046 #include "simbody/internal/common.h" 00047 00048 #include <cassert> 00049 00050 namespace SimTK { 00051 00052 class SimbodyMatterSubsystem; 00053 class SimbodyMatterSubtree; 00054 class MobilizedBody; 00055 class Constraint; 00056 class ConstraintImpl; 00057 00058 // We only want the template instantiation to occur once. This symbol is 00059 // defined in the SimTK core compilation unit that defines the Constraint 00060 // class but should not be defined any other time. 00061 #ifndef SimTK_SIMBODY_DEFINING_CONSTRAINT 00062 extern template class PIMPLHandle<Constraint, ConstraintImpl, true>; 00063 #endif 00064 00066 // CONSTRAINT BASE CLASS // 00068 00074 class SimTK_SIMBODY_EXPORT Constraint : public PIMPLHandle<Constraint, ConstraintImpl, true> { 00075 public: 00076 Constraint() { } 00077 explicit Constraint(ConstraintImpl* r) : HandleBase(r) { } 00078 00082 void disable(State&) const; 00089 void enable(State&) const; 00091 bool isDisabled(const State&) const; 00095 bool isDisabledByDefault() const; 00096 00100 void setDisabledByDefault(bool shouldBeDisabled); 00101 00102 // Implicit conversion to ConstraintIndex when needed. 00103 operator ConstraintIndex() const {return getConstraintIndex();} 00104 00105 // These will fail unless this Constraint is owned by a MatterSubsystem. 00106 ConstraintIndex getConstraintIndex() const; 00107 const SimbodyMatterSubsystem& getMatterSubsystem() const; 00108 SimbodyMatterSubsystem& updMatterSubsystem(); 00109 00110 bool isInSubsystem() const; 00111 bool isInSameSubsystem(const MobilizedBody&) const; 00112 00113 // TOPOLOGY STAGE (i.e., post-construction) // 00114 00120 int getNumConstrainedBodies() const; 00121 00124 const MobilizedBody& 00125 getMobilizedBodyFromConstrainedBody(ConstrainedBodyIndex) const; 00126 00131 const MobilizedBody& getAncestorMobilizedBody() const; 00132 00137 int getNumConstrainedMobilizers() const; 00138 00142 const MobilizedBody& 00143 getMobilizedBodyFromConstrainedMobilizer(ConstrainedMobilizerIndex) const; 00144 00145 const SimbodyMatterSubtree& getSubtree() const; 00146 00147 // MODEL STAGE // 00148 00153 int getNumConstrainedQ(const State&, ConstrainedMobilizerIndex) const; 00158 int getNumConstrainedU(const State&, ConstrainedMobilizerIndex) const; 00159 00166 ConstrainedUIndex getConstrainedUIndex 00167 (const State&, ConstrainedMobilizerIndex, MobilizerUIndex which) const; 00174 ConstrainedQIndex getConstrainedQIndex 00175 (const State&, ConstrainedMobilizerIndex, MobilizerQIndex which) const; 00176 00179 int getNumConstrainedQ(const State&) const; 00180 00185 int getNumConstrainedU(const State&) const; 00186 00190 void getNumConstraintEquationsInUse(const State&, int& mp, int& mv, int& ma) const; 00191 00192 // INSTANCE STAGE // 00193 // nothing in base class currently 00194 00195 // POSITION STAGE // 00198 Vector getPositionErrorsAsVector(const State&) const; // mp of these 00199 Vector calcPositionErrorFromQ(const State&, const Vector& q) const; 00200 00201 // Matrix P = partial(perr_dot)/partial(u). (just the holonomic constraints) 00202 Matrix calcPositionConstraintMatrixP(const State&) const; // mp X nu 00203 Matrix calcPositionConstraintMatrixPt(const State&) const; // nu X mp 00204 00205 // Matrix PNInv = partial(perr)/partial(q) = P*N^-1 00206 Matrix calcPositionConstraintMatrixPNInv(const State&) const; // mp X nq 00207 00221 void calcConstraintForcesFromMultipliers(const State&, 00222 const Vector& lambda, // mp+mv+ma of these 00223 Vector_<SpatialVec>& bodyForcesInA, // numConstrainedBodies 00224 Vector& mobilityForces) const; // numConstrainedU 00225 00226 // VELOCITY STAGE // 00229 Vector getVelocityErrorsAsVector(const State&) const; // mp+mv of these 00230 Vector calcVelocityErrorFromU(const State&, // mp+mv of these 00231 const Vector& u) const; // numParticipatingU u's 00232 00233 // Matrix V = partial(verr)/partial(u) for just the non-holonomic 00234 // constraints. 00235 Matrix calcVelocityConstraintMatrixV(const State&) const; // mv X nu 00236 Matrix calcVelocityConstraintMatrixVt(const State&) const; // nu X mv 00237 00238 // DYNAMICS STAGE // 00239 // nothing in base class currently 00240 00241 // ACCELERATION STAGE // 00245 Vector getAccelerationErrorsAsVector(const State&) const; // mp+mv+ma of these 00246 Vector calcAccelerationErrorFromUDot(const State&, // mp+mv+ma of these 00247 const Vector& udot) const; // numParticipatingU udot's 00248 00252 Vector getMultipliersAsVector(const State&) const; // mp+mv+ma of these 00253 00254 // Matrix A = partial(aerr)/partial(udot) for just the acceleration-only 00255 // constraints. 00256 Matrix calcAccelerationConstraintMatrixA(const State&) const; // ma X nu 00257 Matrix calcAccelerationConstraintMatrixAt(const State&) const; // nu X ma 00258 00259 // These are the built-in Constraint types. Types on the same line are 00260 // synonymous. 00261 class Rod; typedef Rod ConstantDistance; 00262 class Ball; typedef Ball CoincidentPoints; 00263 class Weld; typedef Weld CoincidentFrames; 00264 class PointInPlane; // translations perpendicular to plane normal only 00265 class PointOnLine; // translations along a line only 00266 class ConstantAngle; // prevent rotation about common normal of two vectors 00267 class ConstantOrientation; // allows any translation but no rotation 00268 class NoSlip1D; // same velocity at a point along a direction 00269 class ConstantSpeed; // prescribe generalized speed value 00270 class ConstantAcceleration; // prescribe generalized acceleration value 00271 class Custom; 00272 class CoordinateCoupler; 00273 class SpeedCoupler; 00274 class PrescribedMotion; 00275 00276 class RodImpl; 00277 class BallImpl; 00278 class WeldImpl; 00279 class PointInPlaneImpl; 00280 class PointOnLineImpl; 00281 class ConstantAngleImpl; 00282 class ConstantOrientationImpl; 00283 class NoSlip1DImpl; 00284 class ConstantSpeedImpl; 00285 class ConstantAccelerationImpl; 00286 class CustomImpl; 00287 class CoordinateCouplerImpl; 00288 class SpeedCouplerImpl; 00289 class PrescribedMotionImpl; 00290 }; 00291 00293 // ROD (CONSTANT DISTANCE) CONSTRAINT // 00295 00311 class SimTK_SIMBODY_EXPORT Constraint::Rod : public Constraint { 00312 public: 00313 // no default constructor 00314 Rod(MobilizedBody& body1, MobilizedBody& body2, 00315 Real defaultLength=1); 00316 Rod(MobilizedBody& body1, const Vec3& defaultPoint1, 00317 MobilizedBody& body2, const Vec3& defaultPoint2, 00318 Real defaultLength=1); 00319 00320 // Defaults for Instance variables. 00321 Rod& setDefaultPointOnBody1(const Vec3&); 00322 Rod& setDefaultPointOnBody2(const Vec3&); 00323 Rod& setDefaultRodLength(Real); 00324 00325 // Stage::Topology 00326 MobilizedBodyIndex getBody1MobilizedBodyIndex() const; 00327 MobilizedBodyIndex getBody2MobilizedBodyIndex() const; 00328 const Vec3& getDefaultPointOnBody1() const; 00329 const Vec3& getDefaultPointOnBody2() const; 00330 Real getDefaultRodLength() const; 00331 00332 // Stage::Instance 00333 const Vec3& getPointOnBody1(const State&) const; 00334 const Vec3& getPointOnBody2(const State&) const; 00335 Real getRodLength (const State&) const; 00336 00337 // Stage::Position, Velocity, Acceleration 00338 Real getPositionError(const State&) const; 00339 Real getVelocityError(const State&) const; 00340 00341 // Stage::Acceleration 00342 Real getAccelerationError(const State&) const; 00343 Real getMultiplier(const State&) const; 00344 Real getRodTension(const State&) const; // negative means compression 00345 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Rod, RodImpl, Constraint); 00346 }; 00347 00349 // POINT IN PLANE CONSTRAINT // 00351 00362 class SimTK_SIMBODY_EXPORT Constraint::PointInPlane : public Constraint { 00363 public: 00364 // no default constructor 00365 PointInPlane(MobilizedBody& planeBody_B, const UnitVec3& defaultPlaneNormal_B, Real defaultHeight, 00366 MobilizedBody& followerBody_F, const Vec3& defaultFollowerPoint_F); 00367 00368 // These affect only generated decorative geometry for visualization; 00369 // the plane is really infinite in extent with zero depth and the 00370 // point is really of zero radius. 00371 PointInPlane& setPlaneDisplayHalfWidth(Real); 00372 PointInPlane& setPointDisplayRadius(Real); 00373 Real getPlaneDisplayHalfWidth() const; 00374 Real getPointDisplayRadius() const; 00375 00376 // Defaults for Instance variables. 00377 PointInPlane& setDefaultPlaneNormal(const UnitVec3&); 00378 PointInPlane& setDefaultPlaneHeight(Real); 00379 PointInPlane& setDefaultFollowerPoint(const Vec3&); 00380 00381 // Stage::Topology 00382 MobilizedBodyIndex getPlaneMobilizedBodyIndex() const; 00383 MobilizedBodyIndex getFollowerMobilizedBodyIndex() const; 00384 00385 const UnitVec3& getDefaultPlaneNormal() const; 00386 Real getDefaultPlaneHeight() const; 00387 const Vec3& getDefaultFollowerPoint() const; 00388 00389 // Stage::Instance 00390 const UnitVec3& getPlaneNormal(const State&) const; 00391 Real getPlaneHeight(const State&) const; 00392 const Vec3& getFollowerPoint(const State&) const; 00393 00394 // Stage::Position, Velocity 00395 Real getPositionError(const State&) const; 00396 Real getVelocityError(const State&) const; 00397 00398 // Stage::Acceleration 00399 Real getAccelerationError(const State&) const; 00400 Real getMultiplier(const State&) const; 00401 Real getForceOnFollowerPoint(const State&) const; // in normal direction 00402 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(PointInPlane, PointInPlaneImpl, Constraint); 00403 }; 00404 00406 // POINT ON LINE CONSTRAINT // 00408 00419 class SimTK_SIMBODY_EXPORT Constraint::PointOnLine : public Constraint { 00420 public: 00421 // no default constructor 00422 PointOnLine(MobilizedBody& lineBody_B, const UnitVec3& defaultLineDirection_B, const Vec3& defaultPointOnLine_B, 00423 MobilizedBody& followerBody_F, const Vec3& defaultFollowerPoint_F); 00424 00425 // These affect only generated decorative geometry for visualization; 00426 // the line is really infinite in extent and the 00427 // point is really of zero radius. 00428 PointOnLine& setLineDisplayHalfLength(Real); 00429 PointOnLine& setPointDisplayRadius(Real); 00430 Real getLineDisplayHalfLength() const; 00431 Real getPointDisplayRadius() const; 00432 00433 // Defaults for Instance variables. 00434 PointOnLine& setDefaultLineDirection(const UnitVec3&); 00435 PointOnLine& setDefaultPointOnLine(const Vec3&); 00436 PointOnLine& setDefaultFollowerPoint(const Vec3&); 00437 00438 // Stage::Topology 00439 MobilizedBodyIndex getLineMobilizedBodyIndex() const; 00440 MobilizedBodyIndex getFollowerMobilizedBodyIndex() const; 00441 00442 const UnitVec3& getDefaultLineDirection() const; 00443 const Vec3& getDefaultPointOnLine() const; 00444 const Vec3& getDefaultFollowerPoint() const; 00445 00446 // Stage::Instance 00447 const UnitVec3& getLineDirection(const State&) const; 00448 const Vec3& getPointOnLine(const State&) const; 00449 const Vec3& getFollowerPoint(const State&) const; 00450 00451 // Stage::Position, Velocity 00452 Vec2 getPositionErrors(const State&) const; 00453 Vec2 getVelocityErrors(const State&) const; 00454 00455 // Stage::Acceleration 00456 Vec2 getAccelerationErrors(const State&) const; 00457 Vec2 getMultipliers(const State&) const; 00458 const Vec2& getForceOnFollowerPoint(const State&) const; // in normal direction 00459 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(PointOnLine, PointOnLineImpl, Constraint); 00460 }; 00461 00463 // CONSTANT ANGLE CONSTRAINT // 00465 00494 class SimTK_SIMBODY_EXPORT Constraint::ConstantAngle : public Constraint { 00495 public: 00496 // no default constructor 00497 ConstantAngle(MobilizedBody& baseBody_B, const UnitVec3& defaultAxis_B, 00498 MobilizedBody& followerBody_F, const UnitVec3& defaultAxis_F, 00499 Real angle = Pi/2); 00500 00501 // These affect only generated decorative geometry for visualization. 00502 ConstantAngle& setAxisDisplayLength(Real); 00503 ConstantAngle& setAxisDisplayWidth(Real); 00504 Real getAxisDisplayLength() const; 00505 Real getAxisDisplayWidth() const; 00506 00507 // Defaults for Instance variables. 00508 ConstantAngle& setDefaultBaseAxis(const UnitVec3&); 00509 ConstantAngle& setDefaultFollowerAxis(const UnitVec3&); 00510 ConstantAngle& setDefaultAngle(Real); 00511 00512 // Stage::Topology 00513 MobilizedBodyIndex getBaseMobilizedBodyIndex() const; 00514 MobilizedBodyIndex getFollowerMobilizedBodyIndex() const; 00515 00516 const UnitVec3& getDefaultBaseAxis() const; 00517 const UnitVec3& getDefaultFollowerAxis() const; 00518 Real getDefaultAngle() const; 00519 00520 // Stage::Instance 00521 const UnitVec3& getBaseAxis(const State&) const; 00522 const UnitVec3& getFollowerAxis(const State&) const; 00523 Real getAngle(const State&) const; 00524 00525 // Stage::Position, Velocity 00526 Real getPositionError(const State&) const; 00527 Real getVelocityError(const State&) const; 00528 00529 // Stage::Acceleration 00530 Real getAccelerationError(const State&) const; 00531 Real getMultiplier(const State&) const; 00532 Real getTorqueOnFollowerBody(const State&) const; // about f X b 00533 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(ConstantAngle, ConstantAngleImpl, Constraint); 00534 }; 00535 00537 // BALL (COINCIDENT POINTS) CONSTRAINT // 00539 00553 class SimTK_SIMBODY_EXPORT Constraint::Ball : public Constraint { 00554 public: 00555 // no default constructor 00556 Ball(MobilizedBody& body1, MobilizedBody& body2); 00557 Ball(MobilizedBody& body1, const Vec3& defaultPoint1, 00558 MobilizedBody& body2, const Vec3& defaultPoint2); 00559 00560 // Defaults for Instance variables. 00561 Ball& setDefaultPointOnBody1(const Vec3&); 00562 Ball& setDefaultPointOnBody2(const Vec3&); 00563 00564 // This is used only for visualization. 00565 Ball& setDefaultRadius(Real r); 00566 Real getDefaultRadius() const; 00567 00568 // Stage::Topology 00569 MobilizedBodyIndex getBody1MobilizedBodyIndex() const; 00570 MobilizedBodyIndex getBody2MobilizedBodyIndex() const; 00571 const Vec3& getDefaultPointOnBody1() const; 00572 const Vec3& getDefaultPointOnBody2() const; 00573 00574 // Stage::Instance 00575 const Vec3& getPointOnBody1(const State&) const; 00576 const Vec3& getPointOnBody2(const State&) const; 00577 00578 // Stage::Position, Velocity, Acceleration 00579 Vec3 getPositionErrors(const State&) const; 00580 Vec3 getVelocityErrors(const State&) const; 00581 00582 // Stage::Acceleration 00583 Vec3 getAccelerationErrors(const State&) const; 00584 Vec3 getMultipliers(const State&) const; 00585 00586 // Forces are reported expressed in the body frame of the indicated body. 00587 const Vec3& getBallReactionForceOnBody1(const State&) const; 00588 const Vec3& getBallReactionForceOnBody2(const State&) const; 00589 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Ball, BallImpl, Constraint); 00590 }; 00591 00593 // CONSTANT ORIENTATION CONSTRAINT // 00595 00612 class SimTK_SIMBODY_EXPORT Constraint::ConstantOrientation : public Constraint 00613 { 00614 public: 00615 // no default constructor 00616 ConstantOrientation(MobilizedBody& baseBody_B, const Rotation& defaultRB, 00617 MobilizedBody& followerBody_F, const Rotation& defaultRF); 00618 00619 //TODO: default visualization geometry? 00620 00621 // Defaults for Instance variables. 00622 ConstantOrientation& setDefaultBaseRotation(const Rotation&); 00623 ConstantOrientation& setDefaultFollowerRotation(const Rotation&); 00624 00625 // Stage::Topology 00626 MobilizedBodyIndex getBaseMobilizedBodyIndex() const; 00627 MobilizedBodyIndex getFollowerMobilizedBodyIndex() const; 00628 00629 const Rotation& getDefaultBaseRotation() const; 00630 const Rotation& getDefaultFollowerRotation() const; 00631 00632 // Stage::Instance 00633 const Rotation& getBaseRotation(const State&) const; 00634 const Rotation& getFollowerRotation(const State&) const; 00635 00636 // Stage::Position, Velocity 00637 Vec3 getPositionErrors(const State&) const; 00638 Vec3 getVelocityErrors(const State&) const; 00639 00640 // Stage::Acceleration 00641 Vec3 getAccelerationErrors(const State&) const; 00642 Vec3 getMultipliers(const State&) const; 00643 Vec3 getTorqueOnFollowerBody(const State&) const; 00644 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(ConstantOrientation, ConstantOrientationImpl, Constraint); 00645 }; 00646 00648 // WELD (COINCIDENT FRAMES) CONSTRAINT // 00650 00674 class SimTK_SIMBODY_EXPORT Constraint::Weld : public Constraint { 00675 public: 00676 // no default constructor 00677 00680 Weld(MobilizedBody& body1, MobilizedBody& body2); 00681 00686 Weld(MobilizedBody& body1, const Transform& frame1, 00687 MobilizedBody& body2, const Transform& frame2); 00688 00689 // Control over generated decorative geometry. 00690 00694 Weld& setAxisDisplayLength(Real r); 00695 00699 Real getAxisDisplayLength() const; 00700 00701 // Defaults for Instance variables. 00702 00706 Weld& setDefaultFrameOnBody1(const Transform&); 00707 00709 const Transform& getDefaultFrameOnBody1() const; 00710 00714 Weld& setDefaultFrameOnBody2(const Transform&); 00715 00717 const Transform& getDefaultFrameOnBody2() const; 00718 00719 00720 // Stage::Topology 00721 00723 MobilizedBodyIndex getBody1MobilizedBodyIndex() const; 00724 00726 MobilizedBodyIndex getBody2MobilizedBodyIndex() const; 00727 00728 00729 // Stage::Instance 00730 const Transform& getFrameOnBody1(const State&) const; 00731 const Transform& getFrameOnBody2(const State&) const; 00732 00733 // Stage::Position, Velocity, Acceleration 00734 Vec6 getPositionErrors(const State&) const; 00735 Vec6 getVelocityErrors(const State&) const; 00736 00737 // Stage::Acceleration 00738 Vec6 getAccelerationErrors(const State&) const; 00739 Vec6 getMultipliers(const State&) const; 00740 00741 // Forces are reported expressed in the body frame of the indicated body. 00742 const SpatialVec& getWeldReactionOnBody1(const State&) const; 00743 const SpatialVec& getWeldReactionOnBody2(const State&) const; 00744 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Weld, WeldImpl, Constraint); 00745 }; 00746 00748 // NO SLIP 1D CONSTRAINT // 00750 00762 class SimTK_SIMBODY_EXPORT Constraint::NoSlip1D : public Constraint { 00763 public: 00764 // no default constructor 00765 NoSlip1D(MobilizedBody& caseBodyC, const Vec3& P_C, const UnitVec3& n_C, 00766 MobilizedBody& movingBody0, MobilizedBody& movingBody1); 00767 00768 // These affect only generated decorative geometry for visualization; 00769 // the plane is really infinite in extent with zero depth and the 00770 // point is really of zero radius. 00771 NoSlip1D& setDirectionDisplayLength(Real); 00772 NoSlip1D& setPointDisplayRadius(Real); 00773 Real getDirectionDisplayLength() const; 00774 Real getPointDisplayRadius() const; 00775 00776 // Defaults for Instance variables. 00777 NoSlip1D& setDefaultDirection(const UnitVec3&); 00778 NoSlip1D& setDefaultContactPoint(const Vec3&); 00779 00780 // Stage::Topology 00781 MobilizedBodyIndex getCaseMobilizedBodyIndex() const; 00782 MobilizedBodyIndex getMovingBodyMobilizedBodyIndex(int which) const; 00783 00784 const UnitVec3& getDefaultDirection() const; 00785 const Vec3& getDefaultContactPoint() const; 00786 00787 // Stage::Instance 00788 const UnitVec3& getDirection(const State&) const; 00789 const Vec3& getContactPoint(const State&) const; 00790 00791 // Stage::Position, Velocity 00792 // no position error 00793 Real getVelocityError(const State&) const; 00794 00795 // Stage::Acceleration 00796 Real getAccelerationError(const State&) const; 00797 Real getMultiplier(const State&) const; 00798 Real getForceAtContactPoint(const State&) const; // in normal direction, no body 2 00799 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(NoSlip1D, NoSlip1DImpl, Constraint); 00800 }; 00801 00803 // CONSTANT SPEED // 00805 00812 class SimTK_SIMBODY_EXPORT Constraint::ConstantSpeed : public Constraint 00813 { 00814 public: 00815 // no default constructor 00818 ConstantSpeed(MobilizedBody& mobilizer, MobilizerUIndex, Real speed); 00821 ConstantSpeed(MobilizedBody& mobilizer, Real speed); 00822 00823 // Stage::Topology 00824 MobilizedBodyIndex getMobilizedBodyIndex() const; 00825 MobilizerUIndex getWhichU() const; 00826 Real getDefaultSpeed() const; 00827 00828 // Stage::Position, Velocity 00829 // no position error 00830 Real getVelocityError(const State&) const; 00831 00832 // Stage::Acceleration 00833 Real getAccelerationError(const State&) const; 00834 Real getMultiplier(const State&) const; 00835 Real getGeneralizedForce(const State&) const; 00836 // hide from Doxygen 00838 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS 00839 (ConstantSpeed, ConstantSpeedImpl, Constraint); 00841 }; 00842 00844 // CONSTANT ACCELERATION // 00846 00854 class SimTK_SIMBODY_EXPORT Constraint::ConstantAcceleration : public Constraint 00855 { 00856 public: 00857 // no default constructor 00860 ConstantAcceleration(MobilizedBody& mobilizer, MobilizerUIndex, 00861 Real defaultAcceleration); 00864 ConstantAcceleration(MobilizedBody& mobilizer, 00865 Real defaultAcceleration); 00866 00867 // Stage::Topology 00868 MobilizedBodyIndex getMobilizedBodyIndex() const; 00869 MobilizerUIndex getWhichU() const; 00870 Real getDefaultAcceleration() const; 00871 ConstantAcceleration& setDefaultAcceleration(Real accel); 00872 00875 void setAcceleration(State& state, Real accel) const; 00876 Real getAcceleration(const State& state) const; 00877 00878 // Stage::Position, Velocity 00879 // no position or velocity error 00880 00881 // Stage::Acceleration 00882 Real getAccelerationError(const State&) const; 00883 Real getMultiplier(const State&) const; 00884 Real getGeneralizedForce(const State&) const; 00885 // hide from Doxygen 00887 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS 00888 (ConstantAcceleration, ConstantAccelerationImpl, Constraint); 00890 }; 00891 00926 class SimTK_SIMBODY_EXPORT Constraint::Custom : public Constraint { 00927 public: 00928 class Implementation; 00929 class ImplementationImpl; 00930 00938 explicit Custom(Implementation* implementation); 00939 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Custom, CustomImpl, Constraint); 00940 protected: 00941 const Implementation& getImplementation() const; 00942 Implementation& updImplementation(); 00943 00944 Custom() {} 00945 }; 00946 00947 // We only want the template instantiation to occur once. This symbol is 00948 // defined in the SimTK core compilation unit that defines the Constraint 00949 // class but should not be defined any other time. 00950 #ifndef SimTK_SIMBODY_DEFINING_CONSTRAINT 00951 extern template class PIMPLHandle<Constraint::Custom::Implementation, 00952 Constraint::Custom::ImplementationImpl>; 00953 #endif 00954 00955 class SimTK_SIMBODY_EXPORT Constraint::Custom::Implementation 00956 : public PIMPLHandle<Implementation,ImplementationImpl> { 00957 public: 00958 // No default constructor because you have to supply at least the 00959 // SimbodyMatterSubsystem to which this Constraint belongs. 00960 00963 virtual ~Implementation() { } 00964 00970 virtual Implementation* clone() const = 0; 00971 00976 Implementation(SimbodyMatterSubsystem&, int mp, int mv, int ma); 00977 00982 explicit Implementation(SimbodyMatterSubsystem&); 00983 00984 const SimbodyMatterSubsystem& getMatterSubsystem() const; 00985 00986 // Topological information// 00987 00994 void invalidateTopologyCache() const; 00995 01000 Implementation& setDefaultNumConstraintEquations(int mp, int mv, int ma); 01001 01006 Implementation& setDisabledByDefault(bool shouldBeDisabled); 01007 01013 ConstrainedBodyIndex addConstrainedBody(const MobilizedBody&); 01014 01021 ConstrainedMobilizerIndex addConstrainedMobilizer(const MobilizedBody&); 01022 01023 MobilizedBodyIndex 01024 getMobilizedBodyIndexOfConstrainedBody(ConstrainedBodyIndex) const; 01025 MobilizedBodyIndex 01026 getMobilizedBodyIndexOfConstrainedMobilizer(ConstrainedMobilizerIndex) const; 01027 01028 // Model stage information // 01029 01030 // Methods for use with ConstrainedMobilizers. 01031 01035 Real getOneQ(const State&, ConstrainedMobilizerIndex, MobilizerQIndex) const; 01041 Real getOneU(const State&, ConstrainedMobilizerIndex, MobilizerUIndex) const; 01042 01047 Real getOneQDot (const State&, ConstrainedMobilizerIndex, MobilizerQIndex, bool realizingVelocity=false) const; 01052 Real getOneQDotDot(const State&, ConstrainedMobilizerIndex, MobilizerQIndex, bool realizingAcceleration=false) const; 01057 Real getOneUDot(const State&, ConstrainedMobilizerIndex, MobilizerUIndex, bool realizingAcceleration=false) const; 01058 01065 void addInOneMobilityForce(const State&, 01066 ConstrainedMobilizerIndex, MobilizerUIndex whichU, 01067 Real force, Vector& mobilityForces) const; 01068 01069 // Methods for use with ConstrainedBodies 01070 01074 const Transform& getBodyTransform(const State& s, ConstrainedBodyIndex B) const; // X_AB 01078 const SpatialVec& getBodyVelocity(const State& s, ConstrainedBodyIndex B) const; // V_AB 01082 const SpatialVec& getBodyAcceleration(const State& s, ConstrainedBodyIndex B) const; // A_AB 01083 01084 // Extract just the rotational part of spatial quantities above. 01085 01089 const Rotation& getBodyRotation(const State& s, ConstrainedBodyIndex B) const 01090 {return getBodyTransform(s,B).R();} // R_AB 01094 const Vec3& getBodyAngularVelocity(const State& s, ConstrainedBodyIndex B) const 01095 {return getBodyVelocity(s,B)[0];} // w_AB 01099 const Vec3& getBodyAngularAcceleration(const State& s, ConstrainedBodyIndex B) const 01100 {return getBodyAcceleration(s,B)[0];} // b_AB 01101 01102 // Extract just the translational (linear) part of spatial quantities above. 01103 01108 const Vec3& getBodyOriginLocation(const State& s, ConstrainedBodyIndex B) const 01109 {return getBodyTransform(s,B).p();} // p_AB 01114 const Vec3& getBodyOriginVelocity (const State& s, ConstrainedBodyIndex B) const 01115 {return getBodyVelocity(s,B)[1];} // v_AB 01120 const Vec3& getBodyOriginAcceleration(const State& s, ConstrainedBodyIndex B) const 01121 {return getBodyAcceleration(s,B)[1];} // a_AB 01122 01123 // Calculate location, velocity, and acceleration for a given station. 01124 01131 Vec3 findStationLocation(const State& s, ConstrainedBodyIndex B, const Vec3& p_BS) const { 01132 return getBodyTransform(s,B) * p_BS; // re-measure and re-express 01133 } 01139 Vec3 findStationVelocity(const State& s, ConstrainedBodyIndex B, const Vec3& p_BS) const { 01140 const Vec3 p_AS = getBodyRotation(s,B) * p_BS; // rexpressed but not shifted 01141 const SpatialVec& V_AB = getBodyVelocity(s,B); 01142 return V_AB[1] + (V_AB[0] % p_AS); 01143 } 01149 Vec3 findStationAcceleration(const State& s, ConstrainedBodyIndex B, const Vec3& p_BS) const { 01150 const Vec3 p_AS = getBodyRotation(s,B) * p_BS; // rexpressed but not shifted 01151 const Vec3& w_AB = getBodyAngularVelocity(s,B); 01152 const SpatialVec& A_AB = getBodyAcceleration(s,B); 01153 return A_AB[1] + (A_AB[0] % p_AS) + w_AB % (w_AB % p_AS); // careful: cross product is not associative 01154 } 01155 01156 // Utilities for applying constraint forces to ConstrainedBodies. 01157 01162 void addInStationForce(const State& s, ConstrainedBodyIndex B, 01163 const Vec3& p_BS, 01164 const Vec3& forceInA, Vector_<SpatialVec>& bodyForcesInA) const; 01165 01168 void addInBodyTorque(const State& s, ConstrainedBodyIndex B, 01169 const Vec3& torqueInA, Vector_<SpatialVec>& bodyForcesInA) const; 01170 01171 01172 protected: 01181 01183 01184 01185 01186 01187 01188 01189 01190 01191 virtual void realizeTopology(State&) const { } 01192 01201 virtual void realizeModel(State&) const { } 01202 01206 virtual void realizeInstance(const State&) const { } 01207 01212 virtual void realizeTime(const State&) const { } 01213 01220 virtual void realizePosition(const State&) const { } 01221 01228 virtual void realizeVelocity(const State&) const { } 01229 01234 virtual void realizeDynamics(const State&) const { } 01235 01242 virtual void realizeAcceleration(const State&) const { } 01243 01248 virtual void realizeReport(const State&) const { } 01250 01257 01258 01259 01260 01261 01262 virtual void realizePositionErrors(const State&, int mp, Real* perr) const; 01263 01268 virtual void realizePositionDotErrors(const State&, int mp, Real* pverr) const; 01269 01274 virtual void realizePositionDotDotErrors(const State&, int mp, Real* paerr) const; 01275 01290 virtual void applyPositionConstraintForces 01291 (const State&, int mp, const Real* multipliers, 01292 Vector_<SpatialVec>& bodyForces, 01293 Vector& mobilityForces) const; 01295 01298 01299 01300 01301 01302 01303 virtual void realizeVelocityErrors(const State&, int mv, Real* verr) const; 01304 01309 virtual void realizeVelocityDotErrors(const State&, int mv, Real* vaerr) const; 01310 01325 virtual void applyVelocityConstraintForces 01326 (const State&, int mv, const Real* multipliers, 01327 Vector_<SpatialVec>& bodyForces, 01328 Vector& mobilityForces) const; 01330 01333 01334 01335 01336 01337 01338 virtual void realizeAccelerationErrors(const State&, int ma, Real* aerr) const; 01353 virtual void applyAccelerationConstraintForces 01354 (const State&, int ma, const Real* multipliers, 01355 Vector_<SpatialVec>& bodyForces, 01356 Vector& mobilityForces) const; 01358 01365 virtual void calcDecorativeGeometryAndAppend 01366 (const State& s, Stage stage, Array_<DecorativeGeometry>& geom) const 01367 { 01368 } 01369 01370 friend class Constraint::CustomImpl; 01371 }; 01372 01382 class SimTK_SIMBODY_EXPORT Constraint::CoordinateCoupler 01383 : public Constraint::Custom { 01384 public: 01397 CoordinateCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01398 const Array_<MobilizedBodyIndex>& coordBody, 01399 const Array_<MobilizerQIndex>& coordIndex); 01400 01402 CoordinateCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01403 const std::vector<MobilizedBodyIndex>& coordBody, 01404 const std::vector<MobilizerQIndex>& coordIndex) 01405 { // Invoke the above constructor with converted arguments. 01406 new (this) CoordinateCoupler(matter,function, 01407 ArrayViewConst_<MobilizedBodyIndex>(coordBody), 01408 ArrayViewConst_<MobilizerQIndex>(coordIndex)); 01409 } 01410 }; 01411 01423 class SimTK_SIMBODY_EXPORT Constraint::SpeedCoupler : public Constraint::Custom { 01424 public: 01437 SpeedCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01438 const Array_<MobilizedBodyIndex>& speedBody, 01439 const Array_<MobilizerUIndex>& speedIndex); 01440 01442 SpeedCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01443 const std::vector<MobilizedBodyIndex>& speedBody, 01444 const std::vector<MobilizerUIndex>& speedIndex) 01445 { // Invoke above constructor with converted arguments. 01446 new (this) SpeedCoupler(matter, function, 01447 ArrayViewConst_<MobilizedBodyIndex>(speedBody), 01448 ArrayViewConst_<MobilizerUIndex>(speedIndex)); 01449 } 01450 01467 SpeedCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01468 const Array_<MobilizedBodyIndex>& speedBody, 01469 const Array_<MobilizerUIndex>& speedIndex, 01470 const Array_<MobilizedBodyIndex>& coordBody, 01471 const Array_<MobilizerQIndex>& coordIndex); 01472 01474 SpeedCoupler(SimbodyMatterSubsystem& matter, const Function* function, 01475 const std::vector<MobilizedBodyIndex>& speedBody, 01476 const std::vector<MobilizerUIndex>& speedIndex, 01477 const std::vector<MobilizedBodyIndex>& coordBody, 01478 const std::vector<MobilizerQIndex>& coordIndex) 01479 { // Invoke above constructor with converted arguments. 01480 new (this) SpeedCoupler(matter, function, 01481 ArrayViewConst_<MobilizedBodyIndex>(speedBody), 01482 ArrayViewConst_<MobilizerUIndex>(speedIndex), 01483 ArrayViewConst_<MobilizedBodyIndex>(coordBody), 01484 ArrayViewConst_<MobilizerQIndex>(coordIndex)); 01485 } 01486 }; 01487 01494 class SimTK_SIMBODY_EXPORT Constraint::PrescribedMotion : public Constraint::Custom { 01495 public: 01506 PrescribedMotion(SimbodyMatterSubsystem& matter, const Function* function, 01507 MobilizedBodyIndex coordBody, MobilizerQIndex coordIndex); 01508 }; 01509 01510 } // namespace SimTK 01511 01512 #endif // SimTK_SIMBODY_CONSTRAINT_H_ 01513 01514 01515