1 #ifndef OPENSIM_PHYSICAL_FRAME_H_
2 #define OPENSIM_PHYSICAL_FRAME_H_
3 /* --------------------------------------------------------------------------*
4 *                              OpenSim:  PhysicalFrame.h                     *
5 * -------------------------------------------------------------------------- *
6 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
7 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
8 * OpenSim is developed at Stanford University and supported by the US        *
9 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
10 * through the Warrior Web program.                                           *
11 *                                                                            *
12 * Copyright (c) 2005-2017 Stanford University and the Authors                *
13 * Author(s): Matt DeMers, Ajay Seth, Ayman Habib                             *
14 *                                                                            *
15 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
16 * not use this file except in compliance with the License. You may obtain a  *
17 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
18 *                                                                            *
19 * Unless required by applicable law or agreed to in writing, software        *
20 * distributed under the License is distributed on an "AS IS" BASIS,          *
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
22 * See the License for the specific language governing permissions and        *
23 * limitations under the License.                                             *
24 * -------------------------------------------------------------------------- */
25 
26 // INCLUDE
27 #include <OpenSim/Simulation/Model/Frame.h>
28 #include "simbody/internal/Body.h"
29 
30 // TODO remove these when corresponding properties are removed
31 #include <OpenSim/Simulation/Wrap/WrapObjectSet.h>
32 
33 namespace SimTK {
34 class MobilizedBody;
35 }
36 
37 namespace OpenSim {
38 
39 
40 //=============================================================================
41 //=============================================================================
42 /**
43 * A PhysicalFrame is a Frame that locates a physical element of the multi-
44 * body system that underlies a Model. A PhysicalFrame supports physical
45 * connections (e.g. Joints, Constraints) and is the Frame type upon which
46 * forces can be applied. A concrete example of a PhysicalFrame is a Body.
47 * Attributes of a Body (its center-of-mass, geometry, ...) are located in the
48 * Body frame. Bodies are connected by Joints and Constraints and Forces are
49 * readily applied to them. A location that represents an offset from the Body
50 * frame, can also be a PhysicalFrame (e.g. a PhysicalOffsetFrame).
51 *
52 * @see PhysicalOffsetFrame
53 *
54 * @author Matt DeMers
55 * @author Ajay Seth
56 */
57 
58 class OSIMSIMULATION_API PhysicalFrame : public Frame {
59     OpenSim_DECLARE_ABSTRACT_OBJECT(PhysicalFrame, Frame);
60 
61 public:
62     //==============================================================================
63     // PROPERTIES
64     //==============================================================================
65     /* TODO: Both VisibleObject and the WrapObjectSet should NOT be properties
66     of the PhysicalFrame. This is an intermediate solution as we integrate Frames
67     use into the OpenSim API. These properties should be their own components with
68     Sockets to the PhysicalFrames they attach to. - aseth
69 
70     Note: VisibleObject was removed from this class by @aymanhab via PR #417.
71                                                             -@chrisdembia
72     */
73     OpenSim_DECLARE_UNNAMED_PROPERTY(WrapObjectSet,
74         "Set of wrap objects fixed to this body that GeometryPaths can wrap over."
75         "This property used to be a member of Body but was moved up with "
76         "the introduction of Frames.");
77 
78     //==========================================================================
79     // PUBLIC METHODS
80     //==========================================================================
81 public:
82     //--------------------------------------------------------------------------
83     // CONSTRUCTION
84     //--------------------------------------------------------------------------
85     PhysicalFrame();
86 
~PhysicalFrame()87     virtual ~PhysicalFrame() {}
88 
89     /** @name Advanced: PhysicalFrame's SimTK::MobilizedBody Access
90     Although these methods are public, they are intended for advanced users and
91     developers to access System resources associated with the MobilizedBody that
92     underlies the PhysicalFrame. For example, Solvers operate on the System and
93     not on the OpenSim modeling abstractions, such as Frames.
94     All PhysicalFrames are backed by a SimTK::MobilizedBody, which is the
95     fundamental rigid element of a Simbody SimTK::MultibodySystem. */
96 
97     ///@{
98     /**
99     This method returns the MobilizedBodyIndex of the MobilizedBody for this
100     PhysicalFrame. This index is only available after Model::initSystem() has
101     been invoked.
102 
103     The MobilizedBodyIndex is necessary to access the underlying MobilizedBody
104     in the System. It allows access to physical quantities (e.g. forces)
105     associated with individual PhysicalFrames. For examples, the underlying
106     MultibodySystem's net body forces are represented as a Vector of spatial
107     forces (torque and force on each body) and it is indexed by the
108     MobilizedBodyIndex.
109 
110     @return index The MobilizedBodyIndex corresponding to this PhysicalFrame's
111                underlying MobilizedBody
112 
113     @see getMobilizedBody, updMobilizedBody
114     */
getMobilizedBodyIndex()115     const SimTK::MobilizedBodyIndex& getMobilizedBodyIndex() const {
116         return _mbIndex;
117     }
118 
119     /**
120     Access a readable SimTK::MobilizedBody that backs this PhysicalFrame.
121     The MobilizedBody is only available after Model::initSystem() has been
122     invoked.
123     @see getMobilizedBodyIndex
124     */
125     const SimTK::MobilizedBody& getMobilizedBody() const;
126 
127     /**
128     Access a writable SimTK::MobilizedBody that backs this PhysicalFrame.
129     The MobilizedBody is only available after Model::initSystem() has been
130     invoked.
131     @see getMobilizedBodyIndex
132     */
133     SimTK::MobilizedBody& updMobilizedBody();
134 
135     // End of underlying MobilizedBody accessors.
136     ///@}
137 
138     /** @name DEPRECATED API */
139 
140     ///@{
141     /** Deprecated methods for intermediate integration of Frames */
142     /** Get the named wrap object, if it exists.
143     *
144     * @param aName Name of the wrap object.
145     * @return const Pointer to the wrap object.
146     */
147     const WrapObject* getWrapObject(const std::string& aName) const;
getWrapObjectSet()148     const WrapObjectSet& getWrapObjectSet() const { return get_WrapObjectSet(); }
149 
150     /** Add a wrap object to the Body. Note that the Body takes ownership of
151     * the WrapObject.
152     */
153     void addWrapObject(WrapObject* wrapObject);
154     ///@}
155 
156 protected:
157     /** @name Advanced: PhysicalFrame Developer Interface
158     These methods are intended for PhysicalFrame builders. */
159     ///@{
160     /**
161     Specify the MobilizedBody that implements this PhysicalFrame in the
162     underlying MultibodySystem. The PhysicalFrame's MobilizedBodyIndex must be
163     set by the end of PhysicalFrame::addToSystem()
164         */
165     void setMobilizedBodyIndex(const SimTK::MobilizedBodyIndex& mbix) const;
166 
167     /** Extend how PhysicalFrame determines its base Frame. */
extendFindBaseFrame()168     const Frame& extendFindBaseFrame() const override {
169         return *this;
170     }
171 
172     /** Extend how PhysicalFrame determines its Transform in the base Frame. */
173     SimTK::Transform extendFindTransformInBaseFrame() const override;
174     ///@}
175 
176     /** @name Component Extension methods.
177     PhysicalFrame extension of Component interface. */
178     /**@{**/
179     /// Associate a FrameGeometry (visualization) with the this PhysicalFrame
180     void extendFinalizeFromProperties() override;
181     /// Connect bound WrapObjects
182     void extendConnectToModel(Model& model) override;
183     /**@}**/
184 
185     /** Override to account for version updates in the XML format. */
186     void updateFromXMLNode(SimTK::Xml::Element& aNode,
187         int versionNumber = -1) override;
188 
189 private:
190     /** The transform X_GF for this PhysicalFrame, F, in ground, G. */
191     SimTK::Transform
192         calcTransformInGround(const SimTK::State& state) const override;
193 
194     /** The spatial velocity {omega; v} for this PhysicalFrame in ground. */
195     SimTK::SpatialVec
196         calcVelocityInGround(const SimTK::State& state) const override;
197     /** The spatial acceleration {alpha; a} for this PhysicalFrame in ground */
198     SimTK::SpatialVec
199         calcAccelerationInGround(const SimTK::State& state) const override;
200 
201     /* Component construction interface */
202     void constructProperties();
203 
204     /* Utility to convert Geometry version 3.2 to recent 4.0 format */
205     static void convertDisplayGeometryToGeometryXML(SimTK::Xml::Element& aNode,
206         const SimTK::Vec3& outerScaleFactors,
207         const SimTK::Vec6& outerTransform,
208         SimTK::Xml::Element& geomSetElement);
209 
210     /* Utility for updating XML: add a PhysicalOffsetFrame to the XML element
211     pointed to by ownerIter, and gives the frame the provided name, transform
212     (from the frame's parent frame), and the path (connectee name) to the
213     parent frame.*/
214     static void createFrameForXform(const SimTK::Xml::element_iterator&,
215         const std::string& frameName,
216         const SimTK::Vec6& localXform, const std::string& parentConnecteeName);
217 
218 
219     /* ID for the underlying mobilized body in Simbody system.
220     Only Joint can set, since it defines the mobilized body type and
221     the connection to the parent body in the multibody tree. */
222     SimTK::ResetOnCopy<SimTK::MobilizedBodyIndex> _mbIndex;
223 
extractInternalRigidBody()224     virtual const SimTK::Body& extractInternalRigidBody() const {
225         return _internalRigidBody;
226     }
227 
228     SimTK::Body::Massless _internalRigidBody;
229 
230     // Model is a friend because it creates the underlying mobilized body(ies)
231     // that implement a Joint and is the only component that can assign
232     // the MobilizedBodyIndex for this Body so it can communicate with its
233     // counter-part in the underlying system
234     friend class Joint;
235 
236     //=========================================================================
237 };  // END of class PhysicalFrame
238 
239 //=============================================================================
240 //=============================================================================
241 
242 } // end of namespace OpenSim
243 
244 #endif // OPENSIM_PHYSICAL_FRAME_H_
245 
246 
247