Ejemplo n.º 1
0
        /// Initialization based on passing two vectors (point + dir) on the
        /// two bodies, they will represent the X axes of the two frames (Y and Z will
        /// be built from the X vector via Gram Schmidt orthonormalization).
        /// Use the other ChLinkMateGeneric::Initialize() if you want to set the two frames directly.
        public virtual void Initialize(ChBodyFrame mbody1,    //< first body to link
                                       ChBodyFrame mbody2,    //< second body to link
                                       bool pos_are_relative, //< true: following pos. are relative to bodies.
                                       ChVector mpt1,         //< origin of slave frame 1, for 1st body (rel. or abs., see flag above)
                                       ChVector mpt2,         //< origin of master frame 2, for 2nd body (rel. or abs., see flag above)
                                       ChVector mnorm1,       //< X axis of slave plane, for 1st body (rel. or abs., see flag above)
                                       ChVector mnorm2        //< X axis of master plane, for 2nd body (rel. or abs., see flag above)
                                       )
        {
            Debug.Assert(mbody1 != mbody2);

            this.Body1 = mbody1;
            this.Body2 = mbody2;
            // this.SetSystem(mbody1.GetSystem());

            this.mask.SetTwoBodiesVariables(Body1.Variables(), Body2.Variables());

            ChVector            mx   = new ChVector(0, 0, 0);
            ChVector            my   = new ChVector(0, 0, 0);
            ChVector            mz   = new ChVector(0, 0, 0);
            ChVector            mN   = new ChVector(0, 0, 0);
            ChMatrix33 <double> mrot = new ChMatrix33 <double>();

            ChFrame <double> mfr1 = new ChFrame <double>();
            ChFrame <double> mfr2 = new ChFrame <double>();

            if (pos_are_relative)
            {
                mN = mnorm1;
                mN.DirToDxDyDz(ref mx, ref my, ref mz, new ChVector(0, 1, 0));
                mrot.Set_A_axis(mx, my, mz);
                mfr1.SetRot(mrot);
                mfr1.SetPos(mpt1);

                mN = mnorm2;
                mN.DirToDxDyDz(ref mx, ref my, ref mz, new ChVector(0, 1, 0));
                mrot.Set_A_axis(mx, my, mz);
                mfr2.SetRot(mrot);
                mfr2.SetPos(mpt2);
            }
            else
            {
                ChVector temp = ChVector.VECT_Z;
                // from abs to body-rel
                mN = this.Body1.TransformDirectionParentToLocal(mnorm1);
                mN.DirToDxDyDz(ref mx, ref my, ref mz, temp);
                mrot.Set_A_axis(mx, my, mz);
                mfr1.SetRot(mrot);
                mfr1.SetPos(this.Body1.TransformPointParentToLocal(mpt1));

                mN = this.Body2.TransformDirectionParentToLocal(mnorm2);
                mN.DirToDxDyDz(ref mx, ref my, ref mz, temp);
                mrot.Set_A_axis(mx, my, mz);
                mfr2.SetRot(mrot);
                mfr2.SetPos(this.Body2.TransformPointParentToLocal(mpt2));
            }

            this.frame1 = mfr1;
            this.frame2 = mfr2;
        }
Ejemplo n.º 2
0
        public override void update(double mytime, bool update_assets)
        {
            // Inherit parent class:
            base.update(mytime, update_assets);

            // Override the rotational jacobian [Cq] and the rotational residual C,
            // by assuming an additional hidden frame that rotates about frame2:

            if (this.Body1 != null && this.Body2 != null)
            {
                ChFrame <double> aframe1 = ChFrame <double> .BitShiftRight(this.frame1, (this.Body1));

                ChFrame <double> aframe2 = ChFrame <double> .BitShiftRight(this.frame2, (this.Body2));

                ChFrame <double> aframe12 = new ChFrame <double>();
                aframe2.TransformParentToLocal(aframe1, aframe12);

                ChFrame <double> aframe2rotating = new ChFrame <double>();

                double aux_rotation;

                if (this.avoid_angle_drift)
                {
                    aux_rotation = this.aux_dt + this.rot_offset;
                }
                else
                {
                    // to have it aligned to current rot, to allow C=0.
                    aux_rotation = aframe12.GetRot().Q_to_Rotv().z;
                }

                aframe2rotating.SetRot(aframe2.GetRot() * ChQuaternion.Q_from_AngAxis2(aux_rotation, ChVector.VECT_Z));

                // TODO this needs to be addressed, with it it causes rotation problems, seems to work fine without the TransformParentToLocal?
                ChFrame <double> aframe12rotating = new ChFrame <double>();
                // aframe2rotating.TransformParentToLocal(aframe1, aframe12rotating);

                ChMatrix33 <double> Jw1    = new ChMatrix33 <double>();
                ChMatrix33 <double> Jw2    = new ChMatrix33 <double>();
                ChMatrix33 <double> mtempM = new ChMatrix33 <double>();
                ChMatrix33 <double> mtempQ = new ChMatrix33 <double>();

                ChMatrix33 <double> abs_plane_rotating = aframe2rotating.GetA();

                Jw1.nm.matrix.MatrTMultiply(abs_plane_rotating.nm.matrix, Body1.GetA().nm.matrix);
                Jw2.nm.matrix.MatrTMultiply(abs_plane_rotating.nm.matrix, Body2.GetA().nm.matrix);

                Jw2.nm.matrix.MatrNeg();

                // TODO this also needs to be addressed, with it it causes rotation problems/

                // Premultiply by Jw1 and Jw2 by  0.5*[Fp(q_resid)]' to get residual as imaginary part of a quaternion.

                /* mtempM.Set_X_matrix((aframe12rotating.GetRot().GetVector()) * 0.5);
                 * mtempM[0, 0] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempM[1, 1] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempM[2, 2] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempQ.MatrTMultiply(mtempM, Jw1);
                 * Jw1 = mtempQ;
                 * mtempQ.MatrTMultiply(mtempM, Jw2);
                 * Jw2 = mtempQ;*/

                int nc = 0;

                if (c_x)
                {
                    nc++;
                }
                if (c_y)
                {
                    nc++;
                }
                if (c_z)
                {
                    nc++;
                }
                if (c_rx)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e1;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 0, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 0, 0, 1, 3, 0, 3);
                    nc++;
                }
                if (c_ry)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e2;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 1, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 1, 0, 1, 3, 0, 3);
                    nc++;
                }
                if (c_rz)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e3;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 2, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 2, 0, 1, 3, 0, 3);
                    nc++;
                }
            }
        }
Ejemplo n.º 3
0
        public override void update(double mytime, bool update_assets)
        {
            // Inherit parent class:
            base.update(mytime, update_assets);

            // Override the rotational jacobian [Cq] and the rotational residual C,
            // by assuming an additional hidden frame that rotates about frame2:

            if (this.Body1 != null && this.Body2 != null)
            {
                ChFrame <double> aframe1 = this.frame1.BitShiftRight(this.Body1);
                ChFrame <double> aframe2 = this.frame2.BitShiftRight(this.Body2);

                ChFrame <double> aframe12 = new ChFrame <double>();// ChFrame<double>.FNULL;
                aframe2.TransformParentToLocal(aframe1, aframe12);

                ChFrame <double> aframe2rotating = new ChFrame <double>();// ChFrame<double>.FNULL;

                double aux_rotation;

                aux_rotation = m_func.Get_y(mytime) + rot_offset;

                aframe2rotating.SetRot(aframe2.GetRot() * ChQuaternion.Q_from_AngAxis2(aux_rotation, ChVector.VECT_Z));

                ChFrame <double> aframe12rotating = new ChFrame <double>();
                // aframe2rotating.TransformParentToLocal(aframe1, aframe12rotating);

                ChMatrix33 <double> Jw1 = new ChMatrix33 <double>(0), Jw2 = new ChMatrix33 <double>(0);
                ChMatrix33 <double> mtempM = new ChMatrix33 <double>(0), mtempQ = new ChMatrix33 <double>(0);

                ChMatrix33 <double> abs_plane_rotating = aframe2rotating.GetA();

                Jw1.nm.matrix.MatrTMultiply(abs_plane_rotating.nm.matrix, Body1.GetA().nm.matrix);
                Jw2.nm.matrix.MatrTMultiply(abs_plane_rotating.nm.matrix, Body2.GetA().nm.matrix);

                Jw2.nm.matrix.MatrNeg();

                // Premultiply by Jw1 and Jw2 by  0.5*[Fp(q_resid)]' to get residual as imaginary part of a quaternion.

                /*  mtempM.Set_X_matrix((aframe12rotating.GetRot().GetVector()) * 0.5);
                 * mtempM.nm.matrix[0, 0] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempM.nm.matrix[1, 1] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempM.nm.matrix[2, 2] = 0.5 * aframe12rotating.GetRot().e0;
                 * mtempQ.nm.matrix.MatrTMultiply(mtempM.nm.matrix, Jw1.nm.matrix);
                 * Jw1 = mtempQ;
                 * mtempQ.nm.matrix.MatrTMultiply(mtempM.nm.matrix, Jw2.nm.matrix);
                 * Jw2 = mtempQ;*/

                int nc = 0;

                if (c_x)
                {
                    nc++;
                }
                if (c_y)
                {
                    nc++;
                }
                if (c_z)
                {
                    nc++;
                }
                if (c_rx)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e1;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 0, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 0, 0, 1, 3, 0, 3);
                    nc++;
                }
                if (c_ry)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e2;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 1, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 1, 0, 1, 3, 0, 3);
                    nc++;
                }
                if (c_rz)
                {
                    this.C.matrix.ElementN(nc) = aframe12rotating.GetRot().e3;
                    this.mask.Constr_N(nc).Get_Cq_a().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_b().FillElem(0);
                    this.mask.Constr_N(nc).Get_Cq_a().PasteClippedMatrix(Jw1.nm.matrix, 2, 0, 1, 3, 0, 3);
                    this.mask.Constr_N(nc).Get_Cq_b().PasteClippedMatrix(Jw2.nm.matrix, 2, 0, 1, 3, 0, 3);
                    nc++;
                }
            }
        }