コード例 #1
0
ファイル: Assembler.cpp プロジェクト: thomasklau/simbody
    int gradientFunc(const Vector&     parameters,
                     bool              new_parameters,
                     Vector&           gradient) const override
    {   SimTK_ASSERT2_ALWAYS(gradient.size() == getNumFreeQs(),
            "AssemblySystem::gradientFunc(): expected gradient vector of"
            " size %d but got %d; this is likely a problem with the optimizer"
            " which is required to allocate the right amount of space.",
            getNumFreeQs(), gradient.size());

        ++nEvalGradient;

        if (new_parameters)
            setInternalStateFromFreeQs(parameters);

        for (unsigned i=0; i < assembler.reporters.size(); ++i)
            assembler.reporters[i]->handleEvent(getInternalState());

        // This will record the indices of any goals we encounter that can't
        // provide their own gradients; we'll handle them all together at
        // the end.
        Array_<AssemblyConditionIndex> needNumericalGradient;

        gradient = 0;
        Vector tmpGradient(gradient.size());
        for (unsigned i=0; i < assembler.goals.size(); ++i) {
            AssemblyConditionIndex   goalIx = assembler.goals[i];
            const AssemblyCondition& cond   = *assembler.conditions[goalIx];
            const int stat = (assembler.forceNumericalGradient
                              ? -1
                              : cond.calcGoalGradient(getInternalState(),
                                                      tmpGradient));
            if (stat == -1) {
                needNumericalGradient.push_back(goalIx);
                continue;
            }
            if (stat != 0)
                return stat;

            gradient += assembler.weights[goalIx] * tmpGradient;
        }

        if (!needNumericalGradient.empty()) {
            //cout << "Need numerical gradient for "
            //     << needNumericalGradient.size() << " goals." << endl;
            NumGradientFunc numGoals(assembler, needNumericalGradient);
            // Essential to use central difference here so that the
            // approximate gradient is actually zero at the optimum
            // solution, otherwise IpOpt won't converge.
            Differentiator gradNumGoals
               (numGoals,Differentiator::CentralDifference);
            // weights are already included here
            gradient += gradNumGoals.calcGradient(getFreeQsFromInternalState());

            nEvalObjective += gradNumGoals.getNumCallsToUserFunction();
        }

        //cout << "Grad=" << gradient << endl;

        return 0;
    }
コード例 #2
0
//------------------------------------------------------------------------------
//       REACHING AND GRAVITY COMPENSATION :: CALC DECORATIVE GEOMETRY
//------------------------------------------------------------------------------
void ReachingAndGravityCompensation::
calcDecorativeGeometryAndAppend(const State & state, Stage stage,
                                Array_<DecorativeGeometry>& geometry) const
{
    if (stage != Stage::Position) return;

    const Vec3 targetPos = m_modelTasks.getTarget();
    geometry.push_back(DecorativeSphere(0.02)
            .setTransform(targetPos)
            .setColor(m_targetColor));
    geometry.push_back(DecorativeText("Target: " +
        String(targetPos[0])+","+String(targetPos[1])+","+String(targetPos[2]))
        .setIsScreenText(true));

    const MobilizedBody& ee = m_realRobot.getEndEffectorBody();
    Vec3 taskPosInGround = ee.findStationLocationInGround(state,
                                        m_realRobot.getEndEffectorStation());
    geometry.push_back(DecorativePoint(taskPosInGround)
                       .setColor(Green).setLineThickness(3));

    geometry.push_back(DecorativeText(String("TOGGLES: [t]Task point ")
        + (m_modelTasks.isTaskPointFollowingOn() ? "ON" : "OFF")
        + "...[g]Gravity comp "
        + (m_modelTasks.isGravityCompensationOn() ? "ON" : "OFF")
        + "...[p]Posture control "
        + (m_modelTasks.isPoseControlOn() ? "ON" : "OFF")
        + "...[e]End effector sensor "
        + (m_modelTasks.isEndEffectorSensingOn() ? "ON" : "OFF")
        )
        .setIsScreenText(true));
}
コード例 #3
0
//----------------------------- SET UP VISUALIZER ------------------------------
void MyMechanism::setUpVisualizer() {
    m_viz.setShutdownWhenDestructed(true) // make sure display window dies
         .setBackgroundType(Visualizer::SolidColor); // turn off Ground & Sky

    // Add sliders.
    m_viz.addSlider("Motor speed", SliderIdMotorSpeed,
                    -MaxMotorSpeed, MaxMotorSpeed, InitialMotorSpeed)
         .addSlider("Torque limit", SliderIdTorqueLimit,
                    0, MaxTorqueLimit, InitialTorqueLimit)
         .addSlider("Tach",   SliderIdTach,
                    -MaxMotorSpeed,  MaxMotorSpeed,  0)
         .addSlider("Torque", SliderIdTorque,
                    -InitialTorqueLimit, InitialTorqueLimit, 0);

    // Add Run menu.
    Array_<std::pair<String,int> > runMenuItems;
    runMenuItems.push_back(std::make_pair("Reset", ResetItem));
    runMenuItems.push_back(std::make_pair("Quit", QuitItem));
    m_viz.addMenu("Run", MenuIdRun, runMenuItems);

    // Add per-frame text and geometry.
    m_viz.addDecorationGenerator(new ShowStuff(*this));

    // Add an input listener so the user can talk to us.
    m_userInput = new Visualizer::InputSilo();
    m_viz.addInputListener(m_userInput);
}
コード例 #4
0
void PerSubsystemInfo::
popAllocationStackBackToStage(Array_<T>& stack, const Stage& g) {
    unsigned newSize = stack.size();
    while (newSize > 0 && stack[newSize-1].getAllocationStage() > g)
        stack[--newSize].deepDestruct(*m_stateImpl);
    stack.resize(newSize); 
}
コード例 #5
0
// Create a polygonal mesh for this torus using parameterization as follows:
// u = [0, 2*Pi] traces a circle in the x-y plane with radius torusRadius,
// which is the centroid of the torus. A point P on this circle is
// given by P = torusRadius*~[cos(u) sin(u) 0].
// v = [0, 2*Pi] traces a circle arond the cross-section (or tube) of the
// torus with radius tubeRadius, at a given u. A point Q on this circle
// is given by Q = (torusRadius + tubeRadius*cos(v))*e1 + tubeRadius*(~[0 0 1]*sin(v))
// where e1 = ~[sin(u) cos(u) 0]. The tube circle is in a plane spanned
// by e1 and the z-axis.
void ContactGeometry::Torus::Impl::createPolygonalMesh(PolygonalMesh& mesh) const {
    // TODO add resolution argument
    const int numSides = 12; //*resolution;
    const int numSlices = 36; //*resolution;   

    // add vertices 
    for (int i = 0; i < numSlices; ++i) {
      Real u = Real((i*2*SimTK_PI)/numSlices);
      UnitVec3 e1(std::sin(u), std::cos(u), 0); // torus circle aligned with z-axis (z-axis through hole)
      for (int j = 0; j < numSides; ++j) {
        Real v = Real((j*2*SimTK_PI)/numSides);
        Vec3 vtx = (torusRadius + tubeRadius*std::cos(v))*e1 + tubeRadius*std::sin(v)*Vec3(0,0,1); // use ZAXIS? 
        mesh.addVertex(vtx);  
      }
    }

    // add faces, be careful to wrap indices for the last slice
    int numVertices = mesh.getNumVertices();
//    cout << "num verts = " << numVertices << endl;
    for (int i = 0; i < numVertices; ++i) {
//      cout << "v" << i << ": " << mesh.getVertexPosition(i) << endl;
      // define counter-clockwise quad faces
      Array_<int> faceIndices;
      faceIndices.push_back(i); // u_i,v_i
      faceIndices.push_back((i+1)%numVertices); // u_i, v_i+1
      faceIndices.push_back((i+1+numSides)%numVertices); // u_i+1, v_i+1
      faceIndices.push_back((i+numSides)%numVertices); // u_i+1, v_i
      mesh.addFace(faceIndices);	
    }

}
コード例 #6
0
ファイル: PassThrough.cpp プロジェクト: BrianZ1/simbody
    virtual void generateDecorations(const State& state, Array_<DecorativeGeometry>& geometry) override {
        const Vec3 frcColors[] = {Red,Orange,Cyan};
        const Vec3 momColors[] = {Blue,Green,Purple};
        m_system.realize(state, Stage::Velocity);

        const int ncont = m_compliant.getNumContactForces(state);
        for (int i=0; i < ncont; ++i) {
            const ContactForce& force = m_compliant.getContactForce(state,i);
            const ContactId     id    = force.getContactId();
            const Vec3& frc = force.getForceOnSurface2()[1];

            const Vec3& mom = force.getForceOnSurface2()[0];
            Real  frcMag = frc.norm(), momMag=mom.norm();
            int frcThickness = 1, momThickness = 1;
            Real frcScale = ForceScale, momScale = ForceScale;
            while (frcMag > 10)
                frcThickness++, frcScale /= 10, frcMag /= 10;
            while (momMag > 10)
                momThickness++, momScale /= 10, momMag /= 10;
            DecorativeLine frcLine(force.getContactPoint(),
                                   force.getContactPoint() + frcScale*frc);
            DecorativeLine momLine(force.getContactPoint(),
                                   force.getContactPoint() + momScale*mom);
            frcLine.setColor(frcColors[id%3]);
            momLine.setColor(momColors[id%3]);
            frcLine.setLineThickness(2*frcThickness);
            momLine.setLineThickness(2*momThickness);
            geometry.push_back(frcLine);
            geometry.push_back(momLine);

            ContactPatch patch;
            const bool found = m_compliant.calcContactPatchDetailsById(state,id,patch);
            //cout << "patch for id" << id << " found=" << found << endl;
            //cout << "resultant=" << patch.getContactForce() << endl;
            //cout << "num details=" << patch.getNumDetails() << endl;
            for (int i=0; i < patch.getNumDetails(); ++i) {
                const ContactDetail& detail = patch.getContactDetail(i);
                const Real peakPressure = detail.getPeakPressure();
                // Make a black line from the element's contact point in the normal
                // direction, with length proportional to log(peak pressure)
                // on that element.

                DecorativeLine normal(detail.getContactPoint(),
                                      detail.getContactPoint()+ std::log10(peakPressure)
                                      * detail.getContactNormal());
                normal.setColor(Black);
                geometry.push_back(normal);

                // Make a red line that extends from the contact
                // point in the direction of the slip velocity, of length 3*slipvel.
                DecorativeLine slip(detail.getContactPoint(),
                                    detail.getContactPoint()+3*detail.getSlipVelocity());
                slip.setColor(Red);
                geometry.push_back(slip);
            }
        }
    }
コード例 #7
0
Real CylinderImplicitFunction::
calcDerivative(const Array_<int>& derivComponents, const Vector& x) const {
    if (derivComponents.size() == 1 && derivComponents[0] < 2)
        return -2*x[derivComponents[0]]/square(ownerp->getRadius());
    if (derivComponents.size() == 2 &&
        derivComponents[0] == derivComponents[1] &&
        derivComponents[0] < 2 )
        return -2/square(ownerp->getRadius());
    return 0;
}
コード例 #8
0
Real ObservedPointFitter::findBestFit
   (const MultibodySystem& system, State& state, 
    const Array_<MobilizedBodyIndex>&  bodyIxs, 
    const Array_<Array_<Vec3> >&       stations, 
    const Array_<Array_<Vec3> >&       targetLocations, 
    Real                                        tolerance) 
{
    Array_<Array_<Real> > weights(stations.size());
    for (int i = 0; i < (int)stations.size(); ++i)
        for (int j = 0; j < (int)stations[i].size(); ++j)
            weights[i].push_back(1.0);
    return findBestFit(system, state, bodyIxs, stations, targetLocations, weights, tolerance);
}
コード例 #9
0
// We also rummage through the model to find fixed geometry that should be part
// of every frame. The supplied State must be realized through Instance stage.
void ModelVisualizer::collectFixedGeometry(const State& state) const {
    // Collect any fixed geometry from the ModelComponents.
    Array_<DecorativeGeometry> fixedGeometry;
    _model.generateDecorations
       (true, _model.getDisplayHints(), state, fixedGeometry);

    for (unsigned i=0; i < fixedGeometry.size(); ++i) {
        const DecorativeGeometry& dgeo = fixedGeometry[i];
        //cout << dgeo.getBodyId() << dgeo.getTransform() << endl;
        _viz->addDecoration(MobilizedBodyIndex(dgeo.getBodyId()), 
                            Transform(), dgeo);
    }
}
コード例 #10
0
/** Same as above but for a given time series */
void InverseDynamicsSolver::solve(State &s, const FunctionSet &Qs, const Array_<double> &times, Array_<Vector> &genForceTrajectory)
{
	int nq = getModel().getNumCoordinates();
	int nt = times.size();

	//Preallocate if not done already
	genForceTrajectory.resize(nt, Vector(nq));
	
	AnalysisSet& analysisSet = const_cast<AnalysisSet&>(getModel().getAnalysisSet());
	//fill in results for each time
	for(int i=0; i<nt; i++){ 
		genForceTrajectory[i] = solve(s, Qs, times[i]);
		analysisSet.step(s, i);
	}
}
コード例 #11
0
Real EllipsoidImplicitFunction::
calcDerivative(const Array_<int>& derivComponents, const Vector& x) const {
    const Vec3& radii = ownerp->getRadii();
    if (derivComponents.size() == 1) {
        int c = derivComponents[0];
        return -2*x[c]/(radii[c]*radii[c]);
    }
    if (   derivComponents.size() == 2 
        && derivComponents[0] == derivComponents[1]) {
        int c = derivComponents[0];
        return -2/(radii[c]*radii[c]);
    }
    // A mixed second derivative, or any higher derivative is zero.
    return 0;
}
コード例 #12
0
void Constraint::SphereOnPlaneContactImpl::
calcDecorativeGeometryAndAppendVirtual
   (const State& s, Stage stage, Array_<DecorativeGeometry>& geom) const
{
    // We can't generate the artwork until we know the plane frame and the
    // sphere center and radius, which might not be until Position stage.
    if (   stage == Stage::Position
        && getMyMatterSubsystemRep().getShowDefaultGeometry())
    {
        const SimbodyMatterSubsystemRep& matterRep = getMyMatterSubsystemRep();
        const Parameters& params = getParameters(s);
        const Transform& X_FP = params.m_X_FP;
        const Vec3&      p_BO = params.m_p_BO;
        const Real       r    = params.m_radius;

        // TODO: should be instance-stage data from State rather than
        // topological data.
        // This makes z axis point along plane normal

        const MobilizedBodyIndex planeMBIx =
            getMobilizedBodyIndexOfConstrainedBody(m_planeBody_F);
        const MobilizedBodyIndex ballMBIx =
            getMobilizedBodyIndexOfConstrainedBody(m_ballBody_B);

        if (m_planeHalfWidth > 0) {
            // On the inboard body, draw a gray transparent rectangle,
            // outlined in black lines.
            geom.push_back(DecorativeBrick
               (Vec3(m_planeHalfWidth,m_planeHalfWidth,r/10))
                .setColor(Gray)
                .setRepresentation(DecorativeGeometry::DrawSurface)
                .setOpacity(Real(0.3))
                .setBodyId(planeMBIx)
                .setTransform(X_FP));
            geom.push_back(DecorativeFrame(m_planeHalfWidth/5)
                           .setColor(Gray)
                           .setBodyId(planeMBIx)
                           .setTransform(X_FP));
        }

        // On the ball body draw an orange mesh sphere.
        geom.push_back(DecorativeSphere(r)
            .setColor(Orange)
            .setRepresentation(DecorativeGeometry::DrawWireframe)
            .setBodyId(ballMBIx)
            .setTransform(p_BO));
    }
}
コード例 #13
0
ファイル: Assembler.cpp プロジェクト: thomasklau/simbody
void Assembler::initialize() const {
    if (alreadyInitialized)
        return;

    ++nInitializations;

    Array_<QIndex> toBeLocked;
    reinitializeWithExtraQsLocked(toBeLocked);
    alreadyInitialized = true;
    return;

    /*NOTREACHED*/
    // TODO: This currently unused code would allow the Assembler to lock out
    // variables that it thinks aren't worth bothering with. Needs real-world
    // testing and probably some override options. And should there be a
    // desperation mode where all variables are tried if we can't assemble
    // with some of them removed?
    Vector grad = abs(asmSys->calcCurrentGradient());
    Real maxGrad = 0;
    for (FreeQIndex fx(0); fx < grad.size(); ++fx)
        maxGrad = std::max(maxGrad, grad[fx]);
    if (maxGrad == 0) // no q does anything; probably no objective
        maxGrad = Infinity; // no q will be kept for gradient purposes

    Matrix jac = asmSys->calcCurrentJacobian();
    Vector colNorm(getNumFreeQs());
    Real maxJac = 0;
    for (FreeQIndex fx(0); fx < grad.size(); ++fx) {
        colNorm[fx] = jac(fx).norm();
        maxJac = std::max(maxJac, colNorm[fx]);
    }
    if (maxJac == 0) // no q does anything; probably no constraints
        maxJac = Infinity; // no q will be kept for Jacobian purposes

    const Real QTol = SqrtEps;
    const Real minGradAllowed = maxGrad*QTol;
    const Real minJacAllowed = maxJac*QTol;
    for (FreeQIndex fx(0); fx < grad.size(); ++fx)
        if (grad[fx] < minGradAllowed && colNorm[fx] < minJacAllowed)
            toBeLocked.push_back(getQIndexOfFreeQ(fx));

    if (toBeLocked.size()) {
        cout << "Reinitializing with these q's locked:\n";
        cout << toBeLocked << endl;
        reinitializeWithExtraQsLocked(toBeLocked);
        alreadyInitialized = true;
    }
}
コード例 #14
0
ファイル: ContactBigMeshes.cpp プロジェクト: catskul/simbody
    virtual void generateDecorations(const State& state, Array_<DecorativeGeometry>& geometry) {
        const Vec3 frcColors[] = {Red,Orange,Cyan};
        const Vec3 momColors[] = {Blue,Green,Purple};
        m_system.realize(state, Stage::Velocity);

        const int ncont = m_compliant.getNumContactForces(state);
        for (int i=0; i < ncont; ++i) {
            const ContactForce& force = m_compliant.getContactForce(state,i);
            const ContactId     id    = force.getContactId();
            printf("viz contact %d: id=%d\n", i, (int)id);
            const Vec3& frc = force.getForceOnSurface2()[1];
            const Vec3& mom = force.getForceOnSurface2()[0];
            Real  frcMag = frc.norm(), momMag=mom.norm();
            int frcThickness = 1, momThickness = 1;
            Real frcScale = ForceScale, momScale = ForceScale;
            while (frcMag > 10)
                frcThickness++, frcScale /= 10, frcMag /= 10;
            while (momMag > 10)
                momThickness++, momScale /= 10, momMag /= 10;
            DecorativeLine frcLine(force.getContactPoint(),
                force.getContactPoint() + frcScale*frc);
            DecorativeLine momLine(force.getContactPoint(),
                force.getContactPoint() + momScale*mom);
            frcLine.setColor(frcColors[id%3]);
            momLine.setColor(momColors[id%3]);
            frcLine.setLineThickness(2*frcThickness);
            momLine.setLineThickness(2*momThickness);
            geometry.push_back(frcLine);
            geometry.push_back(momLine);
        }
    }
コード例 #15
0
void ContactGeometry::TriangleMesh::
findVertexEdges(int vertex, Array_<int>& edges) const {
    // Begin at an arbitrary edge which intersects the vertex.

    int firstEdge = getImpl().vertices[vertex].firstEdge;
    int previousEdge = firstEdge;
    int previousFace = getImpl().edges[firstEdge].faces[0];

    // Walk around the vertex, using each edge to find the next face and each
    // face to find the next edge.

    do {
        edges.push_back(previousEdge);
        const ContactGeometry::TriangleMesh::Impl::Edge&
            edge = getImpl().edges[previousEdge];
        int nextFace = (edge.faces[0] == previousFace ? edge.faces[1]
                                                      : edge.faces[0]);
        const ContactGeometry::TriangleMesh::Impl::Face&
            face = getImpl().faces[nextFace];
        int nextEdge;
        if (    face.edges[0] != previousEdge
            && (face.vertices[0] == vertex || face.vertices[1] == vertex))
            nextEdge = face.edges[0];
        else if (   face.edges[1] != previousEdge
                 && (face.vertices[1] == vertex || face.vertices[2] == vertex))
            nextEdge = face.edges[1];
        else
            nextEdge = face.edges[2];
        previousEdge = nextEdge;
        previousFace = nextFace;
    } while (previousEdge != firstEdge);
}
コード例 #16
0
    Real calcDerivative(const Array_<int>& derivComponents, const Vector& x) const
    {
        Real deriv = 0;
    
        assert(3 == x.size());
        
        int derivOrder = derivComponents.size();
        assert(1 <= derivOrder);

        if (derivOrder == 1) 
        {
            // too clever
            //    df/dx
            //  = 2(x-y) + 2(x-z) 
            //  = 2x - 2y + 2x - 2z
            //  = 4x - 2y - 2z
            //  = 6x - 2x - 2y - 2z
            deriv = 2 * (3 * x[derivComponents[0]] -x[0] -x[1] -x[2]);
        }
        else if (derivOrder == 2) 
        {
            if (derivComponents[0] == derivComponents[1])
                deriv = 4.0; // df/dx^2
            else
                deriv = -2.0; // df/dxdy
        } 
        else ; // all derivatives higher than two are zero

        return deriv;
    }
コード例 #17
0
    Real calcDerivative(const Array_<int>& derivComponents, const Vector& x) const{
        Real deriv = 0;
    
        assert(1 == x.size());
        
        // Derivatives repeat after 4
        int derivOrder = derivComponents.size() % 4;

        // Derivatives 1, 5, 9, 13, ... are cos()
        if      ( 1 == derivOrder ) {
            deriv = angle_t(amplitude*cos(x[0]*radians - phase));
        }
        // Derivatives 2, 6, 10, 14, ... are -sin()
        else if ( 2 == derivOrder ) {
            deriv = angle_t(-amplitude*sin(x[0]*radians - phase));
        }
        // Derivatives 3, 7, 11, 15, ... are -cos()
        else if ( 3 == derivOrder ) {
            deriv = angle_t(-amplitude*cos(x[0]*radians - phase));
        }
        // Derivatives 0, 4, 8, 12, ... are sin()
        else if ( 0 == derivOrder ) {
            deriv = angle_t(amplitude*sin(x[0]*radians - phase));
        }
        else assert(false);
        
        return deriv;
    }
コード例 #18
0
int ObservedPointFitter::findBodiesForClonedSystem(MobilizedBodyIndex primaryBodyIx, const Array_<int> numStations, const SimbodyMatterSubsystem& matter, const Array_<Array_<MobilizedBodyIndex> > children, Array_<MobilizedBodyIndex>& bodyIxs) {
    findUpstreamBodies(primaryBodyIx, numStations,  matter, bodyIxs, 5);
    int primaryBodyIndex = bodyIxs.size();
    int requiredStations = 5;
    findDownstreamBodies(primaryBodyIx, numStations, children, bodyIxs, requiredStations);
    return primaryBodyIndex;
}
コード例 #19
0
Real TorusImplicitFunction::
calcDerivative(const Array_<int>& derivComponents, const Vector& x) const {
    // first derivatives
    if (derivComponents.size() == 1) {
        if (derivComponents[0]<2) {
            Real sqrt_xy = std::sqrt(x[0]*x[0] + x[1]*x[1]);
            return 2*x[derivComponents[0]]*(ownerp->getTorusRadius() - sqrt_xy)/
                    (square(ownerp->getTubeRadius())*sqrt_xy);
        }
        else
            return -2*x[2]/square(ownerp->getTubeRadius());
    }

    // second derivatives
    if (derivComponents.size() == 2) {
        if (derivComponents[0] < 2) { // fx_ fy_
            if (derivComponents[1] < 2) {
                Real tubeRadiusSq = square(ownerp->getTubeRadius());
                Real xy = x[0]*x[0] + x[1]*x[1];
                Real sqrt_xy = std::sqrt(xy);
                Real den = tubeRadiusSq*xy*sqrt_xy;
                if (derivComponents[0]==derivComponents[1]) { // fxx or fyy
                    int idx = derivComponents[1]==0; // if 0 then idx=1, if 1 then idx=0
                    Real num = 2*ownerp->getTorusRadius()*x[idx]*x[idx];
                    return num/den - 2/tubeRadiusSq;
                }
                else { // fxy or fyx
                    return - 2*ownerp->getTorusRadius()*x[0]*x[1]/den;
                }
            }
            else // fxz = fyz = 0
                return 0;
        }
        else { // fz_
            if (derivComponents[1] == 2) // fzz
                return -2/square(ownerp->getTubeRadius());
            else // fzx = fzy = 0
                return 0;
        }
    }

    //TODO higher order derivatives
    SimTK_ASSERT1_ALWAYS(!"derivative not implemented",
        "Implicit Torus implements 1st&2nd derivs only but %d deriv requested.",
        derivComponents.size());
    return 0;
}
コード例 #20
0
void ContactGeometry::TriangleMesh::Impl::splitObbAxis
   (const Array_<int>& parentIndices, Array_<int>& child1Indices,
    Array_<int>& child2Indices, int axis)
{   // For each face, find its minimum and maximum extent along the axis.
    Vector minExtent(parentIndices.size());
    Vector maxExtent(parentIndices.size());
    for (int i = 0; i < (int) parentIndices.size(); i++) {
        int* vertexIndices = faces[parentIndices[i]].vertices;
        Real minVal = vertices[vertexIndices[0]].pos[axis];
        Real maxVal = vertices[vertexIndices[0]].pos[axis];
        minVal = std::min(minVal, vertices[vertexIndices[1]].pos[axis]);
        maxVal = std::max(maxVal, vertices[vertexIndices[1]].pos[axis]);
        minExtent[i] = std::min(minVal, vertices[vertexIndices[2]].pos[axis]);
        maxExtent[i] = std::max(maxVal, vertices[vertexIndices[2]].pos[axis]);
    }

    // Select a split point that tries to put as many faces as possible
    // entirely on one side or the other.

    Real split = (median(minExtent)+median(maxExtent)) / 2;

    // Choose a side for each face.

    for (int i = 0; i < (int) parentIndices.size(); i++) {
        if (maxExtent[i] <= split)
            child1Indices.push_back(parentIndices[i]);
        else if (minExtent[i] >= split)
            child2Indices.push_back(parentIndices[i]);
        else if (0.5*(minExtent[i]+maxExtent[i]) <= split)
            child1Indices.push_back(parentIndices[i]);
        else
            child2Indices.push_back(parentIndices[i]);
    }
}
コード例 #21
0
void Constraint::LineOnLineContactImpl::
calcDecorativeGeometryAndAppendVirtual
   (const State& s, Stage stage, Array_<DecorativeGeometry>& geom) const
{
    // We can't generate the artwork until we know the lines' placements,
    // which might not be until Position stage.
    if (   stage != Stage::Position
        || !getMyMatterSubsystemRep().getShowDefaultGeometry())
        return;

    const Parameters&       params = getParameters(s);
    const Real              hf     = params.hf;
    const Real              hb     = params.hb;

    const PositionCache&    pc = ensurePositionCacheRealized(s);
    const Transform&        X_AC = pc.X_AC;

    const MobilizedBody&    mobod_A = getAncestorMobilizedBody();
    const Transform&        X_GA    = mobod_A.getBodyTransform(s);
    const Rotation&         R_GA    = X_GA.R();

    const Transform  X_GC = X_GA * X_AC;

    // Convert interesting stuff from A to G.
    const UnitVec3   df_G  = R_GA * X_AC.x();
    const UnitVec3   db_G  = R_GA * pc.db_A;
    const Vec3       p_GQf = X_GA * pc.p_AQf;
    const Vec3       p_GQb = X_GA * pc.p_AQb;
    const Vec3       half_Lf = hf * df_G;
    const Vec3       half_Lb = hb * db_G;

    const MobilizedBody& bodyF = getMobilizedBodyFromConstrainedBody(m_mobod_F);
    const MobilizedBody& bodyB = getMobilizedBodyFromConstrainedBody(m_mobod_B);

    const Transform& X_GF  = bodyF.getBodyTransform(s);
    const Transform& X_GB  = bodyB.getBodyTransform(s);
    const Transform  X_GEf = X_GF * params.X_FEf;
    const Transform  X_GEb = X_GB * params.X_BEb;


    // On body F draw a green line segment around the orange closest point.
    geom.push_back(DecorativeLine(p_GQf-half_Lf, p_GQf+half_Lf)
        .setColor(Green));
    geom.push_back(DecorativeFrame().setTransform(X_GEf)
        .setColor(Green*.9).setLineThickness(1).setScale(0.5)); // F color
    geom.push_back(DecorativePoint(p_GQf)
        .setColor(Orange).setLineThickness(2)); // B color

    // On body B draw an orange line segment around the green closest point.
    geom.push_back(DecorativeLine(p_GQb-half_Lb, p_GQb+half_Lb)
        .setColor(Orange));
    geom.push_back(DecorativeFrame().setTransform(X_GEb)
        .setColor(Orange*.9).setLineThickness(1).setScale(0.5)); // B color
    geom.push_back(DecorativePoint(p_GQb)
        .setColor(Green).setLineThickness(2)); // F color

    // Show the contact frame in red.
    geom.push_back(DecorativeFrame().setTransform(X_GC)
                   .setColor(Red));
}
コード例 #22
0
ファイル: TestArray.cpp プロジェクト: adamjmendoza/simbody
void testSpeedSimTKArray() {
    Array_<int> v; 
    v.reserve(Inner);

    for (int i=0; i < Outer; ++i) {
        v.clear();
        for (int i=0; i < Inner; ++i)
            v.push_back(i);
    }

    int sum;
    for (int i=0; i < Outer; ++i) {
        sum = i;
        for (unsigned i=0; i < v.size(); ++i)
            sum += v[i];
    }
    cout << "Array sum=" << sum << endl;
}
コード例 #23
0
void ObservedPointFitter::findDownstreamBodies(MobilizedBodyIndex currentBodyIx, const Array_<int> numStations, const Array_<Array_<MobilizedBodyIndex> > children, Array_<MobilizedBodyIndex>& bodyIxs, int& requiredStations) {
    if (numStations[currentBodyIx] == 0 && children[currentBodyIx].empty())
        return; // There's no benefit from including this body.
    bodyIxs.push_back(currentBodyIx);
    requiredStations -= numStations[currentBodyIx];
    for (int i = 0; i < (int)children[currentBodyIx].size() && requiredStations > 0; ++i) {
        findDownstreamBodies(children[currentBodyIx][i], numStations, children, bodyIxs, requiredStations);
    }
}
コード例 #24
0
ファイル: Assembler.cpp プロジェクト: thomasklau/simbody
 NumJacobianFunc(Assembler& assembler,
                 const Array_<AssemblyConditionIndex>& numCons,
                 const Array_<int>& nErrorEqns,
                 int totalNEqns)
 :   Differentiator::JacobianFunction
         (totalNEqns, assembler.getNumFreeQs()),
     assembler(assembler), numCons(numCons), nEqns(nErrorEqns),
     totalNEqns(totalNEqns)
 {   assert(numCons.size() == nEqns.size()); }
コード例 #25
0
void PerSubsystemInfo::copyAllocationStackThroughStage
   (Array_<T>& stack, const Array_<T>& src, const Stage& g) 
{
    unsigned nVarsToCopy = src.size(); // assume we'll copy all
    while (nVarsToCopy && src[nVarsToCopy-1].getAllocationStage() > g)
        --nVarsToCopy;
    resizeAllocationStack(stack, nVarsToCopy);
    for (unsigned i=0; i < nVarsToCopy; ++i)
        stack[i].deepAssign(src[i]);
}
コード例 #26
0
void ObservedPointFitter::findUpstreamBodies(MobilizedBodyIndex currentBodyIx, const Array_<int> numStations, const SimbodyMatterSubsystem& matter, Array_<MobilizedBodyIndex>& bodyIxs, int requiredStations) {
    const MobilizedBody& currentBody = matter.getMobilizedBody(currentBodyIx);
    if (currentBody.isGround())
        return;
    MobilizedBodyIndex parentIx = currentBody.getParentMobilizedBody().getMobilizedBodyIndex();
    requiredStations -= numStations[parentIx];
    if (requiredStations > 0)
        findUpstreamBodies(parentIx, numStations, matter, bodyIxs, requiredStations);
    bodyIxs.push_back(parentIx);
}
コード例 #27
0
ファイル: MiscConstraints.cpp プロジェクト: BrianZ1/simbody
 void calcVelocityDotErrors     
    (const State&                                    s,
     const Array_<SpatialVec,ConstrainedBodyIndex>&  A_AB, 
     const Array_<Real,      ConstrainedUIndex>&     constrainedUDot,
     Array_<Real>&                                   vaerr) const override
 {
     assert(vaerr.size() == 1);
     vaerr[0] = getOneUDot(s, constrainedUDot,
                           theMobilizer, whichMobility);
 }
コード例 #28
0
ファイル: MiscConstraints.cpp プロジェクト: BrianZ1/simbody
 // One non-holonomic (well, velocity-level) constraint equation.
 //    verr = u - s
 //    aerr = udot
 //
 void calcVelocityErrors     
    (const State&                                    s,
     const Array_<SpatialVec,ConstrainedBodyIndex>&  V_AB, 
     const Array_<Real,      ConstrainedUIndex>&     constrainedU,
     Array_<Real>&                                   verr) const override
 {
     assert(verr.size() == 1);
     verr[0] = getOneU(s, constrainedU, theMobilizer, whichMobility) 
             - prescribedSpeed;
 }
コード例 #29
0
ファイル: Subsystem.cpp プロジェクト: BrianZ1/simbody
//------------------------------------------------------------------------------
//                    CALC TIME OF NEXT SCHEDULED REPORT
//------------------------------------------------------------------------------
void Subsystem::Guts::
calcTimeOfNextScheduledReport(const State& state, Real& tNextReport, 
                              Array_<EventId>& eventIds, 
                              bool includeCurrentTime) const 
{
    tNextReport = Infinity;
    eventIds.clear();
    calcTimeOfNextScheduledReportImpl(state, tNextReport, eventIds, 
                                      includeCurrentTime);
}
コード例 #30
0
ファイル: MiscConstraints.cpp プロジェクト: BrianZ1/simbody
 // apply generalized force lambda to the mobility
 void addInVelocityConstraintForcesVirtual
    (const State&                                s, 
     const Array_<Real>&                         multipliers,
     Array_<SpatialVec,ConstrainedBodyIndex>&    bodyForcesInA,
     Array_<Real,ConstrainedUIndex>&             mobilityForces) const
 {
     assert(multipliers.size() == 1);
     const Real lambda = multipliers[0];
     addInOneMobilityForce(s, theMobilizer, whichMobility, 
                           lambda, mobilityForces);
 }