Ejemplo n.º 1
0
Eigen::Matrix<T,4,1> rotate_from_xy(Eigen::Matrix<T,4,1> norm, 
				    Eigen::Matrix<T,4,1> cen, 
				    Eigen::Matrix<T,4,1> vec){
  Eigen::Matrix<T,4,1> vz(0,0,1);
  norm.normalize();
  Eigen::Matrix<T,4,1> xe = -cross(norm,vz).normalize();
  T r1 = norm.mag();
  T o = acos(dot(vz,norm)/r1);
  Eigen::Quaternion<T> dq(cos(o/2.), sin(o/2.)*xe[0], sin(o/2.)*xe[1], sin(o/2.)*xe[2]);	
  Eigen::Matrix<T,4,1> c = dq.rotate(vec);
  c += cen;
  return c;
}
void TransformNDOF::GetJacobian(const scalarArray &q, se3Array &J)
{
	SE3 T = GetTransform(q);
	scalarArray dq(m_iDOF);
	for ( int i = 0; i < m_iDOF; i++ ) dq[i] = q[i];

	for ( int i = 0; i < m_iDOF; i++ )
	{
		dq[i] += m_rEPS;
		J[i] = (SCALAR_1 / m_rEPS) * Linearize(T % GetTransform(dq));
		dq[i] -= m_rEPS;
	}
}
Ejemplo n.º 3
0
/*
  Most pages have similar items, we add their generic data to the JSON
  string here.
*/
QString CreateNewDatabase::genericAddData() {
    std::unique_ptr<QString> ss(new QString(""));
    QString dq("\"");
    QTextStream s(ss.get());
    bool un = false;
    bool nu = false;
    QString rowname;

    switch(ui->stackedWidget->currentIndex())
    {
    case CreateNewDatabase::text:
        rowname = ui->txt_grp_rowname->text();
        un = ui->txt_grp_unique->isChecked();
        nu = ui->txt_grp_isnull->isChecked();
        break;
    case CreateNewDatabase::choice:
        rowname = ui->choice_grp_rowname->text();
        un = ui->choice_grp_unique->isChecked();
        nu = ui->choice_grp_isnull->isChecked();
        break;
    case CreateNewDatabase::date:
        rowname = ui->date_grp_rowname->text();
        un = ui->date_grp_unique->isChecked();
        nu = ui->date_grp_isnull->isChecked();
        break;
    case CreateNewDatabase::time:
        std::runtime_error("Adding time rows is not implemented");
        break;
    case CreateNewDatabase::group:
        std::runtime_error("Adding group rows is not implemented");
        break;
    case CreateNewDatabase::currency:
        rowname = ui->curr_grp_rowname->text();
        un = ui->curr_grp_unique->isChecked();
        nu = ui->curr_grp_isnull->isChecked();
        break;
    default:
        std::runtime_error("Index out of bounds on the buttonGroup, you also need to add the element to the class enum");
        break;
    }

    s << quote(rowname) << ":{"
        // we're using QStrings, so %1, %2 etc refer to positional
        // arguments. They can be filled in with QString::arg(...)
      << quote("ROWNUM") << ":" << "%1" << ","
      << quote("ROWDATA") << ":{"
      << quote("UNIQUE") << ":" << toStrBool(un) << ","
      << quote("NULL") << ":" << toStrBool(nu) << ",";

    return *s.string();
}
void TransformNDOF::GetHessian(const scalarArray &q, se3DbAry &H)
{
	se3Array J(m_iDOF), dJ(m_iDOF);
	
	GetJacobian(q, J);

	scalarArray dq(m_iDOF);
	for ( int i = 0; i < m_iDOF; i++ ) dq[i] = q[i];

	for ( int i = 0; i < m_iDOF; i++ )
	{
		dq[i] += m_rEPS;
		GetJacobian(dq, dJ);
		for ( int j = i + 1; j < m_iDOF; j++ ) H[i][j] = (SCALAR_1 / m_rEPS) * (dJ[j] - J[j]);
		dq[i] -= m_rEPS;
	}
}
Ejemplo n.º 5
0
    bool RTAStar::collisionFree(const Eigen::VectorXd &q_from, const Eigen::VectorXd &dq_from, const KDL::Frame &x_from, const KDL::Frame &x_to, int try_idx, Eigen::VectorXd &q_to, Eigen::VectorXd &dq_to, KDL::Frame &x_to_out,
                            std::list<KDL::Frame > *path_x, std::list<Eigen::VectorXd > *path_q) const {
        path_x->clear();
        path_q->clear();

        Eigen::VectorXd q(ndof_), dq(ndof_), ddq(ndof_);
        ddq.setZero();
        sim_->setTarget(x_to);
        sim_->setState(q_from, dq_from, ddq);
        KDL::Twist diff_target = KDL::diff(x_from, x_to, 1.0);

        for (int loop_counter = 0; loop_counter < 1500; loop_counter++) {
//            Eigen::VectorXd q(ndof_), dq(ndof_), ddq(ndof_);
            sim_->getState(q, dq, ddq);

            KDL::Frame r_HAND_current;
            kin_model_->calculateFk(r_HAND_current, effector_name_, q);

            KDL::Twist prev_diff;
            if (path_x->empty()) {
                prev_diff = KDL::diff(x_from, r_HAND_current, 1.0);
            }
            else {
                prev_diff = KDL::diff(path_x->back(), r_HAND_current, 1.0);
            }

            if (prev_diff.vel.Norm() > 0.1 || prev_diff.rot.Norm() > 30.0/180.0*3.1415) {
                path_x->push_back(r_HAND_current);
                path_q->push_back(q);
            }

            KDL::Twist goal_diff( KDL::diff(r_HAND_current, x_to, 1.0) );
            if (goal_diff.vel.Norm() < 0.01) {// && goal_diff.rot.Norm() < 5.0/180.0*3.1415) {
                q_to = q;
                dq_to = dq;
                x_to_out = r_HAND_current;
                return true;
            }

            sim_->oneStep();
            if (sim_->inCollision()) {
                return false;
            }
        }
        return false;
    }
	static dFloat PlaneMeshCollisionRayHitCallback (NewtonUserMeshCollisionRayHitDesc* const rayDesc)
	{
		dVector q0 (rayDesc->m_p0[0], rayDesc->m_p0[1], rayDesc->m_p0[2]);
		dVector q1 (rayDesc->m_p1[0], rayDesc->m_p1[1], rayDesc->m_p1[2]);
		dVector dq (q1 - q0);

		// calculate intersection between point lien a plane and return intersection parameter
		dInfinitePlane* const me = (dInfinitePlane*) rayDesc->m_userData;
		dFloat t = -(me->m_plane.DotProduct3(q0) + me->m_plane.m_w) / (me->m_plane.DotProduct3(dq));
		if ((t > 0.0f) && (t < 1.0f)) {
			rayDesc->m_normalOut[0] = me->m_plane[0];
			rayDesc->m_normalOut[1] = me->m_plane[1];
			rayDesc->m_normalOut[2] = me->m_plane[2];
		} else {
			t = 1.2f;
		}
		return t;
	}
Ejemplo n.º 7
0
Eigen::Matrix<T,4,1> rotate_to_plane(Eigen::Matrix<T,4,1> normP, 
				     Eigen::Matrix<T,4,1> norm, 
				     Eigen::Matrix<T,4,1> cen, 
				     Eigen::Matrix<T,4,1> vec){
  norm.normalize();
  normP.normalize();	
  Eigen::Matrix<T,4,1> xe = cross(norm,normP).normalize();
  T r1 = norm.mag();
  T rP = normP.mag();
  T o = acos(dot(normP,norm)/r1/rP) - M_PI;
  T o0 = acos(dot(normP,norm)/r1/rP);
  Eigen::Quaternion<T> qP(normP);
  Eigen::Quaternion<T> qi(norm);
  //	Eigen::Quaternion<T>  dq = (qP-qi).normalize();
  Eigen::Quaternion<T> dq(cos(o/2.), sin(o/2.)*xe[0], sin(o/2.)*xe[1], sin(o/2.)*xe[2]);		
  //	Eigen::Quaternion<T> dq = qP*qi.conj()*qP;
  Eigen::Matrix<T,4,1> c = dq.normalize().rotate(vec - cen);
  return c;
}
Ejemplo n.º 8
0
dgVector dgQuaternion::CalcAverageOmega (const dgQuaternion &q1, dgFloat32 invdt) const
{
	dgQuaternion q0 (*this);
	if (q0.DotProduct (q1) < 0.0f) {
		q0.Scale(-1.0f);
	}
	dgQuaternion dq (q0.Inverse() * q1);
	dgVector omegaDir (dq.m_q1, dq.m_q2, dq.m_q3, dgFloat32 (0.0f));

	dgFloat32 dirMag2 = omegaDir % omegaDir;
	if (dirMag2	< dgFloat32(dgFloat32 (1.0e-5f) * dgFloat32 (1.0e-5f))) {
		return dgVector (dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
	}

	dgFloat32 dirMagInv = dgRsqrt (dirMag2);
	dgFloat32 dirMag = dirMag2 * dirMagInv;

	dgFloat32 omegaMag = dgFloat32(2.0f) * dgAtan2 (dirMag, dq.m_q0) * invdt;
	return omegaDir.Scale3 (dirMagInv * omegaMag);
}
Ejemplo n.º 9
0
dVector dQuaternion::CalcAverageOmega (const dQuaternion &q1, dFloat invdt) const
{
	dQuaternion q0 (*this);
	if (q0.DotProduct (q1) < 0.0f) {
		q0.Scale(-1.0f);
	}
	dQuaternion dq (q0.Inverse() * q1);
	dVector omegaDir (dq.m_q1, dq.m_q2, dq.m_q3);

	dFloat dirMag2 = omegaDir % omegaDir;
	if (dirMag2	< dFloat(dFloat (1.0e-5f) * dFloat (1.0e-5f))) {
		return dVector (dFloat(0.0f), dFloat(0.0f), dFloat(0.0f), dFloat(0.0f));
	}

	dFloat dirMagInv = dFloat (1.0f) / dSqrt (dirMag2);
	dFloat dirMag = dirMag2 * dirMagInv;

	dFloat omegaMag = dFloat(2.0f) * dAtan2 (dirMag, dq.m_q0) * invdt;
	return omegaDir.Scale (dirMagInv * omegaMag);
}
Ejemplo n.º 10
0
void printlevel(struct BT *root)
    {
    
        if(!root)
            return;
            
          struct Q *q=createQ(MAX);
          nq(q,root);
          
          while(!isEmpty(q))
            {
                root=dq(q);
                printf("[%d]\t",root->data);
                
                if(root->l)
                    nq(q,root->l);
                if(root->r)
                    nq(q,root->r);    
            }   
    }                           
Ejemplo n.º 11
0
/*
  Generates the json string for the CHOICE type.
*/
QString CreateNewDatabase::generateChoiceData() {
    std::unique_ptr<QString> ss(new QString(""));
    QString dq("\"");
    QTextStream s(ss.get());

    QStringList choices = ui->choice_grp_choices->toPlainText().split("\n");
    choices.removeDuplicates();

    s << genericAddData()
      << quote("TYPE", "CHOICE") << ","
      << quote("CHOICES") << ":[";
    for (int x = 0; x < choices.size(); ++x) {
        s << dq << choices[x] << dq;
        if (x + 1 != choices.size())
            s << ",";
    }
    s << "]}}";

    return *s.string();
}
Ejemplo n.º 12
0
void DynamicChain2D::GetCoriolisForceMatrix(Matrix& C)
{
	std::vector<Matrix> dBdi(q.n);
	for(int z=0;z<q.n;z++)
		GetKineticEnergyMatrixDeriv(z,dBdi[z]);
	C.resize(q.n,q.n);
	Update_dB_dq();
	for(int i=0;i<q.n;i++) {
		for(int j=0;j<q.n;j++) {
			C(i,j) = Zero;
			for(int k=0;k<q.n;k++) {
				Real dbij_dqk,dbik_dqj,dbjk_dqi;
				dbij_dqk=dB_dq[k](i,j);
				dbik_dqj=dB_dq[j](i,k);
				dbjk_dqi=dB_dq[i](j,k);
				C(i,j) += (dbij_dqk + dbik_dqj - dbjk_dqi)*dq(k);
			}
			C(i,j)*=Half;
		}
	}
}
Ejemplo n.º 13
0
int test_inverse() 
{
	int Error(0);

	float const Epsilon = 0.0001f;

	glm::dualquat dqid;
	glm::mat4x4 mid(1.0f);

	for (int j = 0; j < 100; ++j)
	{
		glm::mat4x4 rot = glm::yawPitchRoll(myfrand() * 360.0f, myfrand() * 360.0f, myfrand() * 360.0f);
		glm::vec3 vt = glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f);

		glm::mat4x4 m = glm::translate(mid, vt) * rot;

		glm::quat qr = glm::quat_cast(m);

		glm::dualquat dq(qr);

		glm::dualquat invdq = glm::inverse(dq);

		glm::dualquat r1 = invdq * dq;
		glm::dualquat r2 = dq * invdq;

		Error += glm::all(glm::epsilonEqual(r1.real, dqid.real, Epsilon)) && glm::all(glm::epsilonEqual(r1.dual, dqid.dual, Epsilon)) ? 0 : 1;
		Error += glm::all(glm::epsilonEqual(r2.real, dqid.real, Epsilon)) && glm::all(glm::epsilonEqual(r2.dual, dqid.dual, Epsilon)) ? 0 : 1;

		// testing commutative property
		glm::dualquat r (   glm::quat( myfrand() * glm::pi<float>() * 2.0f, myfrand(), myfrand(), myfrand() ),
							glm::vec3(myfrand() * 10.0f, myfrand() * 10.0f, myfrand() * 10.0f) );
		glm::dualquat riq = (r * invdq) * dq;
		glm::dualquat rqi = (r * dq) * invdq;

		Error += glm::all(glm::epsilonEqual(riq.real, rqi.real, Epsilon)) && glm::all(glm::epsilonEqual(riq.dual, rqi.dual, Epsilon)) ? 0 : 1;
	}

	return Error;
}
Ejemplo n.º 14
0
void FreeJoint::updateJacobianTimeDeriv() {
  Eigen::Vector3d q(mCoordinate[0].get_q(),
                    mCoordinate[1].get_q(),
                    mCoordinate[2].get_q());
  Eigen::Vector3d dq(mCoordinate[0].get_dq(),
                     mCoordinate[1].get_dq(),
                     mCoordinate[2].get_dq());

  Eigen::Matrix3d dJ = math::expMapJacDot(q, dq);

  Eigen::Vector6d dJ0;
  Eigen::Vector6d dJ1;
  Eigen::Vector6d dJ2;
  Eigen::Vector6d J3;
  Eigen::Vector6d J4;
  Eigen::Vector6d J5;

  dJ0 << dJ(0, 0), dJ(0, 1), dJ(0, 2), 0, 0, 0;
  dJ1 << dJ(1, 0), dJ(1, 1), dJ(1, 2), 0, 0, 0;
  dJ2 << dJ(2, 0), dJ(2, 1), dJ(2, 2), 0, 0, 0;
  J3 << 0, 0, 0, 1, 0, 0;
  J4 << 0, 0, 0, 0, 1, 0;
  J5 << 0, 0, 0, 0, 0, 1;

  mdS.col(0) = math::AdT(mT_ChildBodyToJoint, dJ0);
  mdS.col(1) = math::AdT(mT_ChildBodyToJoint, dJ1);
  mdS.col(2) = math::AdT(mT_ChildBodyToJoint, dJ2);
  mdS.col(3) =
      -math::ad(mS.leftCols<3>() * get_dq().head<3>(),
                math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J3));
  mdS.col(4) =
      -math::ad(mS.leftCols<3>() * get_dq().head<3>(),
                math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J4));
  mdS.col(5) =
      -math::ad(mS.leftCols<3>() * get_dq().head<3>(),
                math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J5));

  assert(!math::isNan(mdS));
}
Ejemplo n.º 15
0
void bfsIterative(int node){
	visited[node] = 1;
	inq(node);
	// visited[node] = 1;
	// printf("%c ", dic[node]);
	while(start < end){
		//printf("%d %d\n", start , end);
		int next_node = dq();
		printf("%c ", dic[next_node]);
		int i;
		for(i = A; i <= G; i++) {
			if(!visited[i] && g[next_node][i]) {
				visited[i] = 1;
				inq(i);
			}
		}
		
		// int j;
		// for(j = 0; j <= MAX_N; j++) printf("%c ", dic[Q[j]]);
		// printf("\n");
	}
}
Ejemplo n.º 16
0
dVector dQuaternion::CalcAverageOmega (const dQuaternion &QB, dFloat dt) const
{
    dFloat dirMag;
    dFloat dirMag2;
    dFloat omegaMag;
    dFloat dirMagInv;


    dQuaternion dq (Inverse() * QB);
    dVector omegaDir (dq.m_q1, dq.m_q2, dq.m_q3);

    dirMag2 = omegaDir % omegaDir;
    if (dirMag2	< dFloat(dFloat (1.0e-5f) * dFloat (1.0e-5f))) {
        return dVector (dFloat(0.0f), dFloat(0.0f), dFloat(0.0f), dFloat(0.0f));
    }

    dirMagInv = dFloat (1.0f) / dSqrt (dirMag2);
    dirMag = dirMag2 * dirMagInv;

    omegaMag = dFloat(2.0f) * dAtan2 (dirMag, dq.m_q0) / dt;

    return omegaDir.Scale (dirMagInv * omegaMag);
}
Ejemplo n.º 17
0
inline void BallJoint::updateJacobianTimeDeriv()
{
    Eigen::Vector3d q(mCoordinate[0].get_q(),
                      mCoordinate[1].get_q(),
                      mCoordinate[2].get_q());
    Eigen::Vector3d dq(mCoordinate[0].get_dq(),
                       mCoordinate[1].get_dq(),
                       mCoordinate[2].get_dq());

    Eigen::Matrix3d dJ = math::expMapJacDot(q, dq);

    Eigen::Vector6d dJ0;
    Eigen::Vector6d dJ1;
    Eigen::Vector6d dJ2;

    dJ0 << dJ(0,0), dJ(0,1), dJ(0,2), 0, 0, 0;
    dJ1 << dJ(1,0), dJ(1,1), dJ(1,2), 0, 0, 0;
    dJ2 << dJ(2,0), dJ(2,1), dJ(2,2), 0, 0, 0;

    mdS.col(0) = math::AdT(mT_ChildBodyToJoint, dJ0);
    mdS.col(1) = math::AdT(mT_ChildBodyToJoint, dJ1);
    mdS.col(2) = math::AdT(mT_ChildBodyToJoint, dJ2);
}
Ejemplo n.º 18
0
void insert(struct BT **root,struct Q *q,int d)
    {
        struct BT *temp=nn(d);
        
        if(!*root)
            *root=temp;
            
         else
            {
                struct BT *front=get(q);
                
                if(!front->l)
                    front->l=temp;
               else  if(!front->r)
                    front->r=temp;  
                     
                if(hasdouble(front))
                    dq(q);
            
            }
            
           nq(q,temp);    
     
    } 
Ejemplo n.º 19
0
void FreeJoint::_updateAcceleration()
{
    // dS
    Eigen::Vector3d q(mCoordinate[0].get_q(),
                      mCoordinate[1].get_q(),
                      mCoordinate[2].get_q());
    Eigen::Vector3d dq(mCoordinate[0].get_dq(),
                       mCoordinate[1].get_dq(),
                       mCoordinate[2].get_dq());

    Eigen::Matrix3d dJ = math::expMapJacDot(q, dq);

    Eigen::Vector6d dJ0;
    Eigen::Vector6d dJ1;
    Eigen::Vector6d dJ2;
    Eigen::Vector6d J3;
    Eigen::Vector6d J4;
    Eigen::Vector6d J5;

    dJ0 << dJ(0,0), dJ(0,1), dJ(0,2), 0, 0, 0;
    dJ1 << dJ(1,0), dJ(1,1), dJ(1,2), 0, 0, 0;
    dJ2 << dJ(2,0), dJ(2,1), dJ(2,2), 0, 0, 0;
    J3 << 0, 0, 0, 1, 0, 0;
    J4 << 0, 0, 0, 0, 1, 0;
    J5 << 0, 0, 0, 0, 0, 1;

    mdS.col(0) = math::AdT(mT_ChildBodyToJoint, dJ0);
    mdS.col(1) = math::AdT(mT_ChildBodyToJoint, dJ1);
    mdS.col(2) = math::AdT(mT_ChildBodyToJoint, dJ2);
    mdS.col(3) = -math::ad(mS.leftCols<3>() * get_dq().head<3>(), math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J3));
    mdS.col(4) = -math::ad(mS.leftCols<3>() * get_dq().head<3>(), math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J4));
    mdS.col(5) = -math::ad(mS.leftCols<3>() * get_dq().head<3>(), math::AdT(mT_ChildBodyToJoint * math::expAngular(-q), J5));

    // dV = dS * dq + S * ddq
    mdV = mdS * get_dq() + mS * get_ddq();
}
Ejemplo n.º 20
0
RTC::ReturnCode_t TorqueController::onExecute(RTC::UniqueId ec_id)
{ 
  m_loop++;

  // make timestamp
  coil::TimeValue coiltm(coil::gettimeofday());
  hrp::dvector dq(m_robot->numJoints());
  RTC::Time tm;
  tm.sec = coiltm.sec();
  tm.nsec = coiltm.usec()*1000;
  
  // update port
  if (m_tauCurrentInIn.isNew()) {
    m_tauCurrentInIn.read();
  }
  if (m_tauMaxInIn.isNew()) {
    m_tauMaxInIn.read();
  }
  if (m_qCurrentInIn.isNew()) {
    m_qCurrentInIn.read();
  }
  if (m_qRefInIn.isNew()) {
    m_qRefInIn.read();
  }

  if (m_qRefIn.data.length() == m_robot->numJoints() &&
      m_tauCurrentIn.data.length() == m_robot->numJoints() &&
      m_qCurrentIn.data.length() == m_robot->numJoints()) {

    // update model
    for ( int i = 0; i < m_robot->numJoints(); i++ ){
        m_robot->joint(i)->q = m_qCurrentIn.data[i];
    }
    m_robot->calcForwardKinematics();   

    // calculate dq by torque controller
    executeTorqueControl(dq);

    // output restricted qRef
    for (int i = 0; i < m_robot->numJoints(); i++) {
      m_qRefOut.data[i] = std::min(std::max(m_qRefIn.data[i] + dq[i], m_robot->joint(i)->llimit), m_robot->joint(i)->ulimit);
    }
  } else {
    if (isDebug()) {
      std::cerr << "TorqueController input is not correct" << std::endl;
      std::cerr << " numJoints: " << m_robot->numJoints() << std::endl;
      std::cerr << "  qCurrent: " << m_qCurrentIn.data.length() << std::endl;
      std::cerr << "    qRefIn: " << m_qRefIn.data.length() << std::endl;
      std::cerr << "tauCurrent: " << m_tauCurrentIn.data.length() << std::endl;
      std::cerr << std::endl;
    }
    // pass qRefIn to qRefOut
    for (int i = 0; i < m_robot->numJoints(); i++) {
      m_qRefOut.data[i] = m_qRefIn.data[i];
    }
  }

  m_qRefOut.tm = tm;
  m_qRefOutOut.write();

  return RTC::RTC_OK;
}
Ejemplo n.º 21
0
    bool add(control_ptr ob, long i, long j, T teni, T tenj){
      //	m2::subdivide<T> sub;
      //	m2Ch = sub.subdivide_control(m2Ch);
      //bezier_curve<point_space<3,T> > mCurve(3);
      face_ptr fi = ob->face(i);
      face_ptr fj = ob->face(j);
			
      bezier_curve<point_space<3,typename SPACE::type> > mCurve(4);	
      coordinate_type c0 = fi->calculate_center();	
      coordinate_type c0t = c0 + teni*ob->face(i)->normal();
      coordinate_type c1 = fj->calculate_center();	
      coordinate_type c1t = c1 + tenj*ob->face(j)->normal();			
			
      if (fi->size() != fj->size() ) {
	return false;
      }
			
      mCurve.push_point(c0);
      mCurve.push_point(c0t);	
      mCurve.push_point(c1t);		
      mCurve.push_point(c1);
			
      mCurve.update_knot_vector();
			
			
      Eigen::Quaternion<T>  q1(ob->face(j)->normal());q1.normalize();			
			
      vector<coordinate_type > f0 = fi->coordinate_trace();
      vector<coordinate_type > f1 = fj->coordinate_trace();
			
      long Ni = mCurve.mKnots.size();
      T dt = T(1./T(Ni-1));
      T t = dt*0.5;
      //						for(long ii = 0; ii < 3; ++ii){			
      for(long ii = 0; ii < Ni-1; ++ii){
	coordinate_type Ni = fi->normal();
	Eigen::Quaternion<T>  q0(Ni); q0.normalize();
	coordinate_type de = mCurve.mKnots[ii]-mCurve.mKnots[ii+1];
	de.normalize();
	Eigen::Quaternion<T> qi(de); qi.normalize();
	//
	coordinate_type xe = cross(Ni,-de).normalize();
	T r0 = de.mag();
	T r1 = Ni.mag();
	T o = acos(dot(-de,Ni)/r0/r1);
				
	Eigen::Quaternion<T> dq(cos(o/2.), sin(o/2.)*xe[0], sin(o/2.)*xe[1], sin(o/2.)*xe[2]);
	//				Eigen::Quaternion<T> dq = (qi*q0); //dq[0]*=M_PI;
	//dq.normalize();			
	coordinate_type cen = fi->calculate_center();
	face_vertex_ptr itb = fi->fbegin();
	face_vertex_ptr ite = fi->fend();
				
	construct<SPACE> bevel;
	bevel.bevel_face(ob, fi, 0.0, 0.0);			
				
	bool at_head = false;
	while (!at_head) {
	  at_head = itb == ite;
	  coordinate_type c = itb->coordinate();
	  coordinate_type cp0 = dq.rotate(c-cen);
	  itb->coordinate() = cp0 + (mCurve.mKnots[ii+1]);
	  itb = itb->next();					
	}
				
	fi->update_normal();
	fi->update_center();				
	this->slerp_face(t, fi, fj);				
	//				cen = fi->calculate_center();
	//				itb = fi->fbegin();
	//				at_head = false;
	//				while (!at_head) {
	//					at_head = itb == ite;
	//					coordinate_type c = itb->coordinate();
	//					coordinate_type N = fi->normal();
	//					T o = 0.5*t*M_PI;
	//					Eigen::Quaternion<T> qb(cos(o*0.5), sin(o*0.5)*N[0], sin(o*0.5)*N[1], sin(o*0.5)*N[2]);
	//					qb.normalize();
	//					Eigen::Matrix<T,4,1> cp1 = qb.rotate(c-cen);
	//					//					Eigen::Matrix<T,4,1> cp1 = cp0;
	//					//					itb->coordinate() = cp0 + (mCurve.mKnots[ii] + mCurve.mKnots[ii + 1])*0.5;
	//					itb->coordinate() = cp1 + (mCurve.mKnots[ii+1]);
	//					itb = itb->next();					
	//				}
				
	t += dt;
      }
      graph_skinning<SPACE> gs; //TODO: stitch_faces needs to get moved to a surgery object
      gs.stitch_faces(ob, fi, fj, 0.01);
      return true;
    }
dgFloat32 dgCollisionChamferCylinder::RayCast (const dgVector& q0, const dgVector& q1, dgFloat32 maxT, dgContactPoint& contactOut, const dgBody* const body, void* const userData, OnRayPrecastAction preFilter) const
{
	if (q0.m_x > m_height) {
		if (q1.m_x < m_height) {
			dgFloat32 t1 = (m_height - q0.m_x) / (q1.m_x - q0.m_x);
			dgFloat32 y = q0.m_y + (q1.m_y - q0.m_y) * t1;
			dgFloat32 z = q0.m_z + (q1.m_z - q0.m_z) * t1;
			if ((y * y + z * z) < m_radius * m_radius) {
				contactOut.m_normal = dgVector (dgFloat32 (1.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
				//contactOut.m_userId = SetUserDataID();
				return t1; 
			}
		}
	}

	if (q0.m_x < -m_height) {
		if (q1.m_x > -m_height) {
			dgFloat32 t1 = (-m_height - q0.m_x) / (q1.m_x - q0.m_x);
			dgFloat32 y = q0.m_y + (q1.m_y - q0.m_y) * t1;
			dgFloat32 z = q0.m_z + (q1.m_z - q0.m_z) * t1;
			if ((y * y + z * z) < m_radius * m_radius) {
				contactOut.m_normal = dgVector (dgFloat32 (-1.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
				//contactOut.m_userId = SetUserDataID();
				return t1; 
			}
		}
	}

	dgVector dq ((q1 - q0) & dgVector::m_triplexMask);
	
	// avoid NaN as a result of a division by zero
	if ((dq % dq) <= 0.0f) {
		return dgFloat32(1.2f);
	}

	//dgVector dir (dq.Scale3 (dgRsqrt(dq % dq)));
	dgVector dir (dq.CompProduct4 (dq.InvMagSqrt()));
	if (dgAbsf (dir.m_x) > 0.9999f) {
		return dgCollisionConvex::RayCast (q0, q1, maxT, contactOut, NULL, NULL, NULL);
	}

	dgVector p0 (q0);
	dgVector p1 (q1);
	dgVector dp (dq);

	p0.m_x = dgFloat32 (0.0f);
	p1.m_x = dgFloat32 (0.0f);
	dp.m_x = dgFloat32 (0.0f);

	dgFloat32 a = dp % dp;
	//dgFloat32 b = dgFloat32 (2.0f) * (p0 % dp);
	dgFloat32 b = dgFloat32 (2.0f) * (p0.DotProduct4(dp).GetScalar());
	dgFloat32 r = m_radius + m_height;
	dgFloat32 c = p0 % p0 - r * r;
	dgFloat32 desc = b * b - dgFloat32 (4.0f) * a * c;
	if (desc >= 0.0f) {
		desc = dgSqrt (desc);
		dgFloat32 den = dgFloat32 (0.5f) / a;
		dgFloat32 s0 = (-b + desc) * den;
		dgFloat32 s1 = (-b - desc) * den;

		dgVector origin0 (p0 + dp.Scale4 (s0));
		dgVector origin1 (p0 + dp.Scale4 (s1));
		dgFloat32 s = m_radius / (m_radius + m_height);
		origin0 = origin0.Scale4 (s);
		origin1 = origin1.Scale4 (s);
		dgFloat32 t0 = dgRayCastSphere (q0, q1, origin0, m_height);
		dgFloat32 t1 = dgRayCastSphere (q0, q1, origin1, m_height);
		if (t0 < t1) {
			if ((t0 >= 0.0f) && (t0 <= 1.0f)) {
				contactOut.m_normal = q0 + dq.Scale4 (t0) - origin0;
				dgAssert (contactOut.m_normal.m_w == dgFloat32 (0.0f));
				//contactOut.m_normal = contactOut.m_normal.Scale3 (dgRsqrt (contactOut.m_normal % contactOut.m_normal));
				contactOut.m_normal = contactOut.m_normal.CompProduct4(contactOut.m_normal.DotProduct4(contactOut.m_normal).InvSqrt());
				//contactOut.m_userId = SetUserDataID();
				return t0; 
			}
		} else {
			if ((t1 >= 0.0f) && (t1 <= 1.0f)) {
				contactOut.m_normal = q0 + dq.Scale4 (t1) - origin1;
				dgAssert (contactOut.m_normal.m_w == dgFloat32 (0.0f));
				//contactOut.m_normal = contactOut.m_normal.Scale3 (dgRsqrt (contactOut.m_normal % contactOut.m_normal));
				contactOut.m_normal = contactOut.m_normal.CompProduct4(contactOut.m_normal.DotProduct4(contactOut.m_normal).InvSqrt());
				//contactOut.m_userId = SetUserDataID();
				return t1; 
			}
		}
	}

	return dgFloat32 (1.2f);
}
Ejemplo n.º 23
0
  void AnimeshObject::Skin ()
  {
    if (!skeleton)
      return;

    CS_ASSERT (SkinV ?
	       skinnedVertices->GetElementCount () >= factory->vertexCount : true);
    CS_ASSERT (SkinN ?
	       skinnedNormals->GetElementCount () >= factory->vertexCount : true);
    CS_ASSERT (SkinTB ?
	       skinnedTangents->GetElementCount () >= factory->vertexCount
	       && skinnedBinormals->GetElementCount () >= factory->vertexCount
	       : true);

    // Setup some local data
    csVertexListWalker<float, csVector3> srcVerts (postMorphVertices);
    csRenderBufferLock<csVector3> dstVerts (skinnedVertices);
    csVertexListWalker<float, csVector3> srcNormals (factory->normalBuffer);
    csRenderBufferLock<csVector3> dstNormals (skinnedNormals);

    csVertexListWalker<float, csVector3> srcTangents (factory->tangentBuffer);
    csRenderBufferLock<csVector3> dstTangents (skinnedTangents);
    csVertexListWalker<float, csVector3> srcBinormals (factory->binormalBuffer);
    csRenderBufferLock<csVector3> dstBinormals (skinnedBinormals);

    csSkeletalState2* skeletonState = lastSkeletonState;

    csAnimatedMeshBoneInfluence* influence = factory->boneInfluences.GetArray ();

    for (size_t i = 0; i < factory->vertexCount; ++i)
    {
      // Accumulate data for the vertex
      int numInfluences = 0;

      csDualQuaternion dq (csQuaternion (0,0,0,0), csQuaternion (0,0,0,0)); 
      csQuaternion pivot;

      for (size_t j = 0; j < 4; ++j, ++influence) // @@SOLVE 4
      {
        if (influence->influenceWeight > 0.0f)
        {
          numInfluences++;

          csDualQuaternion inflQuat (
            skeletonState->GetQuaternion (influence->bone),
            skeletonState->GetVector (influence->bone));

          if (numInfluences == 1)
          {
            pivot = inflQuat.real;
          }
          else if (inflQuat.real.Dot (pivot) < 0.0f)
          {
            inflQuat *= -1.0f;
          }

          dq += inflQuat * influence->influenceWeight;
        }
      }   

      if (numInfluences == 0)
      {
        if (SkinV)
        {
          dstVerts[i] = *srcVerts;
        }

        if (SkinN)
        {
          dstNormals[i] = *srcNormals;
        }        

        if (SkinTB)
        {
          dstTangents[i] = *srcTangents;
          dstBinormals[i] = *srcBinormals;
        }        
      }
      else
      {
        dq = dq.Unit ();

        if (SkinV)
        {
          dstVerts[i] = dq.TransformPoint (*srcVerts);
        }

        if (SkinN)
        {
          dstNormals[i] = dq.Transform (*srcNormals);
        }

        if (SkinTB)
        {
          dstTangents[i] = dq.Transform (*srcTangents);
          dstBinormals[i] = dq.Transform (*srcBinormals);
        }       
      }

      ++srcVerts;
      ++srcNormals;
      ++srcTangents;
      ++srcBinormals;
    }
  }
Ejemplo n.º 24
0
void 
UZRectMollerup::tick (const GeometryRect& geo,
		      const std::vector<size_t>& drain_cell,
		      const double drain_water_level,
		      const Soil& soil, 
		      SoilWater& soil_water, const SoilHeat& soil_heat,
		      const Surface& surface, const Groundwater& groundwater,
		      const double dt, Treelog& msg)

{
  daisy_assert (K_average.get ());
  const size_t edge_size = geo.edge_size (); // number of edges 
  const size_t cell_size = geo.cell_size (); // number of cells 

  // Insert magic here.
  
  ublas::vector<double> Theta (cell_size); // water content 
  ublas::vector<double> Theta_previous (cell_size); // at start of small t-step
  ublas::vector<double> h (cell_size); // matrix pressure
  ublas::vector<double> h_previous (cell_size); // at start of small timestep
  ublas::vector<double> h_ice (cell_size); // 
  ublas::vector<double> S (cell_size); // sink term
  ublas::vector<double> S_vol (cell_size); // sink term
#ifdef TEST_OM_DEN_ER_BRUGT
  ublas::vector<double> S_macro (cell_size);  // sink term
  std::vector<double> S_drain (cell_size, 0.0); // matrix-> macro -> drain flow 
  std::vector<double> S_drain_sum (cell_size, 0.0); // For large timestep
  const std::vector<double> S_matrix (cell_size, 0.0);  // matrix -> macro 
  std::vector<double> S_matrix_sum (cell_size, 0.0); // for large timestep
#endif
  ublas::vector<double> T (cell_size); // temperature 
  ublas::vector<double> Kold (edge_size); // old hydraulic conductivity
  ublas::vector<double> Ksum (edge_size); // Hansen hydraulic conductivity
  ublas::vector<double> Kcell (cell_size); // hydraulic conductivity
  ublas::vector<double> Kold_cell (cell_size); // old hydraulic conductivity
  ublas::vector<double> Ksum_cell (cell_size); // Hansen hydraulic conductivity
  ublas::vector<double> h_lysimeter (cell_size);
  std::vector<bool> active_lysimeter (cell_size);
  const std::vector<size_t>& edge_above = geo.cell_edges (Geometry::cell_above);
  const size_t edge_above_size = edge_above.size ();
  ublas::vector<double> remaining_water (edge_above_size);
  std::vector<bool> drain_cell_on (drain_cell.size (),false); 
  

  for (size_t i = 0; i < edge_above_size; i++)
    {
      const size_t edge = edge_above[i];
      remaining_water (i) = surface.h_top (geo, edge);
    }
  ublas::vector<double> q;	// Accumulated flux
  q = ublas::zero_vector<double> (edge_size);
  ublas::vector<double> dq (edge_size); // Flux in small timestep.
  dq = ublas::zero_vector<double> (edge_size);

  //Make Qmat area diagonal matrix 
  //Note: This only needs to be calculated once... 
  ublas::banded_matrix<double> Qmat (cell_size, cell_size, 0, 0);
  for (int c = 0; c < cell_size; c++)
    Qmat (c, c) = geo.cell_volume (c);
 
  // make vectors 
  for (size_t cell = 0; cell != cell_size ; ++cell) 
    {				
      Theta (cell) = soil_water.Theta (cell);
      h (cell) =  soil_water.h (cell);
      h_ice (cell) = soil_water.h_ice (cell);
      S (cell) =  soil_water.S_sum (cell);
      S_vol (cell) = S (cell) * geo.cell_volume (cell);
      if (use_forced_T)
	T (cell) = forced_T;
      else 
	T (cell) = soil_heat.T (cell); 
      h_lysimeter (cell) = geo.zplus (cell) - geo.cell_z (cell);
    }

  // Remember old value.
  Theta_error = Theta;

  // Start time loop 
  double time_left = dt;	// How much of the large time step left.
  double ddt = dt;		// We start with small == large time step.
  int number_of_time_step_reductions = 0;
  int iterations_with_this_time_step = 0;
  

  int n_small_time_steps = 0;
  
  while (time_left > 0.0)
    {
      if (ddt > time_left)
	ddt = time_left;

      std::ostringstream tmp_ddt;
      tmp_ddt << "Time t = " << (dt - time_left) 
              << "; ddt = " << ddt
              << "; steps " << n_small_time_steps 
              << "; time left = " << time_left;
      Treelog::Open nest (msg, tmp_ddt.str ());

      if (n_small_time_steps > 0
          && (n_small_time_steps%msg_number_of_small_time_steps) == 0)
        {
          msg.touch ();
          msg.flush ();
        }
      
      n_small_time_steps++;
      if (n_small_time_steps > max_number_of_small_time_steps) 
        {
          msg.debug ("Too many small timesteps");
          throw "Too many small timesteps";
        }
      
      // Initialization for each small time step.

      if (debug > 0)
	{
	  std::ostringstream tmp;
	  tmp << "h = " << h << "\n";
	  tmp << "Theta = " << Theta;
	  msg.message (tmp.str ());
	}

      int iterations_used = 0;
      h_previous = h;
      Theta_previous = Theta;

      if (debug == 5)
	{
	  std::ostringstream tmp;
	  tmp << "Remaining water at start: " << remaining_water;
	  msg.message (tmp.str ());
	}

      ublas::vector<double> h_conv;

      for (size_t cell = 0; cell != cell_size ; ++cell)
        active_lysimeter[cell] = h (cell) > h_lysimeter (cell);

      for (size_t edge = 0; edge != edge_size ; ++edge)
        {
          Kold[edge] = find_K_edge (soil, geo, edge, h, h_ice, h_previous, T);
          Ksum [edge] = 0.0;
        }

      std::vector<top_state> state (edge_above.size (), top_undecided);
      
      // We try harder with smaller timesteps.
      const int max_loop_iter 
        = max_iterations * (number_of_time_step_reductions 
                            * max_iterations_timestep_reduction_factor + 1);
      do // Start iteration loop
	{
	  h_conv = h;
	  iterations_used++;
          

          std::ostringstream tmp_conv;
          tmp_conv << "Convergence " << iterations_used; 
          Treelog::Open nest (msg, tmp_conv.str ());
          if (debug == 7)
            msg.touch ();

	  // Calculate conductivity - The Hansen method
	  for (size_t e = 0; e < edge_size; e++)
	    {
              Ksum[e] += find_K_edge (soil, geo, e, h, h_ice, h_previous, T);
              Kedge[e] = (Ksum[e] / (iterations_used  + 0.0)+ Kold[e]) / 2.0;
	    }

	  //Initialize diffusive matrix
	  Solver::Matrix diff (cell_size);
	  // diff = ublas::zero_matrix<double> (cell_size, cell_size);
	  diffusion (geo, Kedge, diff);

	  //Initialize gravitational matrix
	  ublas::vector<double> grav (cell_size); //ublass compatibility
	  grav = ublas::zero_vector<double> (cell_size);
	  gravitation (geo, Kedge, grav);

	  // Boundary matrices and vectors
	  ublas::banded_matrix<double>  Dm_mat (cell_size, cell_size, 
                                                0, 0); // Dir bc
	  Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size);
	  ublas::vector<double>  Dm_vec (cell_size); // Dir bc
	  Dm_vec = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> Gm (cell_size); // Dir bc
	  Gm = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> B (cell_size); // Neu bc 
	  B = ublas::zero_vector<double> (cell_size);

	  lowerboundary (geo, groundwater, active_lysimeter, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, msg);
	  upperboundary (geo, soil, T, surface, state, remaining_water, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt);
          Darcy (geo, Kedge, h, dq); //for calculating drain fluxes 


	  //Initialize water capacity  matrix
	  ublas::banded_matrix<double> Cw (cell_size, cell_size, 0, 0);
	  for (size_t c = 0; c < cell_size; c++)
	    Cw (c, c) = soil.Cw2 (c, h[c]);
	  
          std::vector<double> h_std (cell_size);
          //ublas vector -> std vector 
          std::copy(h.begin (), h.end (), h_std.begin ());

#ifdef TEST_OM_DEN_ER_BRUGT
          for (size_t cell = 0; cell != cell_size ; ++cell) 
            {				
              S_macro (cell) = (S_matrix[cell] + S_drain[cell]) 
                * geo.cell_volume (cell);
            }
#endif

	  //Initialize sum matrix
	  Solver::Matrix summat (cell_size);  
	  noalias (summat) = diff + Dm_mat;

	  //Initialize sum vector
	  ublas::vector<double> sumvec (cell_size);  
	  sumvec = grav + B + Gm + Dm_vec - S_vol
#ifdef TEST_OM_DEN_ER_BRUGT
            - S_macro
#endif
            ; 

	  // QCw is shorthand for Qmatrix * Cw
	  Solver::Matrix Q_Cw (cell_size);
	  noalias (Q_Cw) = prod (Qmat, Cw);

	  //Initialize A-matrix
	  Solver::Matrix A (cell_size);  
	  noalias (A) = (1.0 / ddt) * Q_Cw - summat;  

	  // Q_Cw_h is shorthand for Qmatrix * Cw * h
	  const ublas::vector<double> Q_Cw_h = prod (Q_Cw, h);

	  //Initialize b-vector
	  ublas::vector<double> b (cell_size);  
	  //b = sumvec + (1.0 / ddt) * (Qmatrix * Cw * h + Qmatrix *(Wxx-Wyy));
	  b = sumvec + (1.0 / ddt) * (Q_Cw_h
				      + prod (Qmat, Theta_previous-Theta));

	  // Force active drains to zero h.
          drain (geo, drain_cell, drain_water_level,
		 h, Theta_previous, Theta, S_vol,
#ifdef TEST_OM_DEN_ER_BRUGT
                 S_macro,
#endif
                 dq, ddt, drain_cell_on, A, b, debug, msg);  
          
          try {
            solver->solve (A, b, h); // Solve Ah=b with regard to h.
          } catch (const char *const error) {
              std::ostringstream tmp;
              tmp << "Could not solve equation system: " << error;
              msg.warning (tmp.str ());
              // Try smaller timestep.
              iterations_used = max_loop_iter + 100;
              break;
          }

	  for (int c=0; c < cell_size; c++) // update Theta 
	    Theta (c) = soil.Theta (c, h (c), h_ice (c)); 

	  if (debug > 1)
	    {
	      std::ostringstream tmp;
	      tmp << "Time left = " << time_left << ", ddt = " << ddt 
		  << ", iteration = " << iterations_used << "\n";
	      tmp << "B = " << B << "\n";
	      tmp << "h = " << h << "\n";
	      tmp << "Theta = " << Theta;
	      msg.message (tmp.str ());
	    }
          
          for (int c=0; c < cell_size; c++)
            {
              if (h (c) < min_pressure_potential || h (c) > max_pressure_potential)
                {
                  std::ostringstream tmp;
                  tmp << "Pressure potential out of realistic range, h[" 
                      << c << "] = " << h (c);
                  msg.debug (tmp.str ());
                  iterations_used = max_loop_iter + 100;
                  break;
                } 
            }
        }

      while (!converges (h_conv, h) && iterations_used <= max_loop_iter);
      

      if (iterations_used > max_loop_iter)
	{
          number_of_time_step_reductions++;
          
	  if (number_of_time_step_reductions > max_time_step_reductions)
            {
              msg.debug ("Could not find solution");
              throw "Could not find solution";
            }

          iterations_with_this_time_step = 0;
	  ddt /= time_step_reduction;
	  h = h_previous;
	  Theta = Theta_previous;
	}
      else
	{
          // Update dq for new h.
	  ublas::banded_matrix<double>  Dm_mat (cell_size, cell_size, 
                                                0, 0); // Dir bc
	  Dm_mat = ublas::zero_matrix<double> (cell_size, cell_size);
	  ublas::vector<double>  Dm_vec (cell_size); // Dir bc
	  Dm_vec = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> Gm (cell_size); // Dir bc
	  Gm = ublas::zero_vector<double> (cell_size);
	  ublas::vector<double> B (cell_size); // Neu bc 
	  B = ublas::zero_vector<double> (cell_size);
	  lowerboundary (geo, groundwater, active_lysimeter, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, msg);
	  upperboundary (geo, soil, T, surface, state, remaining_water, h,
                         Kedge,
                         dq, Dm_mat, Dm_vec, Gm, B, ddt, debug, msg, dt);
          Darcy (geo, Kedge, h, dq);

#ifdef TEST_OM_DEN_ER_BRUGT
          // update macropore flow components 
          for (int c = 0; c < cell_size; c++)
            {
              S_drain_sum[c] += S_drain[c] * ddt/dt;
              S_matrix_sum[c] += S_matrix[c] * ddt/dt;
            }
#endif

          std::vector<double> h_std_new (cell_size);
          std::copy(h.begin (), h.end (), h_std_new.begin ());

	  // Update remaining_water.
	  for (size_t i = 0; i < edge_above.size (); i++)
	    {
	      const int edge = edge_above[i];
	      const int cell = geo.edge_other (edge, Geometry::cell_above);
	      const double out_sign = (cell == geo.edge_from (edge))
		? 1.0 : -1.0;
	      remaining_water[i] += out_sign * dq (edge) * ddt;
              daisy_assert (std::isfinite (dq (edge)));
	    }

	  if (debug == 5)
	    {
	      std::ostringstream tmp;
	      tmp << "Remaining water at end: " << remaining_water;
	      msg.message (tmp.str ());
	    }

	  // Contribution to large time step.
          daisy_assert (std::isnormal (dt));
          daisy_assert (std::isnormal (ddt));
	  q += dq * ddt / dt;
          for (size_t e = 0; e < edge_size; e++)
            {
              daisy_assert (std::isfinite (dq (e)));
              daisy_assert (std::isfinite (q (e)));
            }
          for (size_t e = 0; e < edge_size; e++)
            {
              daisy_assert (std::isfinite (dq (e)));
              daisy_assert (std::isfinite (q (e)));
            }

	  time_left -= ddt;
	  iterations_with_this_time_step++;

	  if (iterations_with_this_time_step > time_step_reduction)
	    {
	      number_of_time_step_reductions--;
	      iterations_with_this_time_step = 0;
	      ddt *= time_step_reduction;
	    }
	}
      // End of small time step.
    }

  // Mass balance.
  // New = Old - S * dt + q_in * dt - q_out * dt + Error =>
  // 0 = Old - New - S * dt + q_in * dt - q_out * dt + Error
  Theta_error -= Theta;         // Old - New
  Theta_error -= S * dt;
#ifdef TEST_OM_DEN_ER_BRUGT
  for (size_t c = 0; c < cell_size; c++)
    Theta_error (c) -= (S_matrix_sum[c] + S_drain_sum[c]) * dt;
#endif
  
  for (size_t edge = 0; edge != edge_size; ++edge) 
    {
      const int from = geo.edge_from (edge);
      const int to = geo.edge_to (edge);
      const double flux = q (edge) * geo.edge_area (edge) * dt;
      if (geo.cell_is_internal (from))
        Theta_error (from) -= flux / geo.cell_volume (from);
      if (geo.cell_is_internal (to))
        Theta_error (to) += flux / geo.cell_volume (to);
    }

  // Find drain sink from mass balance.
#ifdef TEST_OM_DEN_ER_BRUGT
  std::fill(S_drain.begin (), S_drain.end (), 0.0);
#else
  std::vector<double> S_drain (cell_size);
#endif
  for (size_t i = 0; i < drain_cell.size (); i++)
    {
      const size_t cell = drain_cell[i];
      S_drain[cell] = Theta_error (cell) / dt;
      Theta_error (cell) -= S_drain[cell] * dt;
    }

  if (debug == 2)
    {
      double total_error = 0.0;
      double total_abs_error = 0.0;
      double max_error = 0.0;
      int max_cell = -1;
      for (size_t cell = 0; cell != cell_size; ++cell) 
        {
          const double volume = geo.cell_volume (cell);
          const double error = Theta_error (cell);
          total_error += volume * error;
          total_abs_error += std::fabs (volume * error);
          if (std::fabs (error) > std::fabs (max_error))
            {
              max_error = error;
              max_cell = cell;
            }
        }
      std::ostringstream tmp;
      tmp << "Total error = " << total_error << " [cm^3], abs = " 
	  << total_abs_error << " [cm^3], max = " << max_error << " [] in cell " 
	  << max_cell;
      msg.message (tmp.str ());
    }
  
  // Make it official.
  for (size_t cell = 0; cell != cell_size; ++cell) 
    soil_water.set_content (cell, h (cell), Theta (cell));
  
#ifdef TEST_OM_DEN_ER_BRUGT
  soil_water.add_tertiary_sink (S_matrix_sum);
  soil_water.drain (S_drain_sum, msg);
#endif


  for (size_t edge = 0; edge != edge_size; ++edge) 
    {
      daisy_assert (std::isfinite (q[edge]));
      soil_water.set_flux (edge, q[edge]);
    }

  soil_water.drain (S_drain, msg);

  // End of large time step.
}
		bool
		JacobianInverseKinematics::solve()
		{
			::std::chrono::steady_clock::time_point start = ::std::chrono::steady_clock::now();
			double remaining = ::std::chrono::duration<double>(this->getDuration()).count();
			::std::size_t iteration = 0;
			
			::rl::math::Vector q = this->kinematic->getPosition();
			::rl::math::Vector q2(this->kinematic->getDofPosition());
			::rl::math::Vector dq(this->kinematic->getDofPosition());
			::rl::math::Vector dx(6 * this->kinematic->getOperationalDof());
			
			::rl::math::Vector rand(this->kinematic->getDof());
			
			do
			{
				do
				{
					this->kinematic->forwardPosition();
					dx.setZero();
					
					for (::std::size_t i = 0; i < this->goals.size(); ++i)
					{
						::rl::math::VectorBlock dxi = dx.segment(6 * this->goals[i].second, 6);
						dxi = this->kinematic->getOperationalPosition(this->goals[i].second).toDelta(this->goals[i].first);
					}
					
					if (dx.squaredNorm() < ::std::pow(this->getEpsilon(), 2))
					{
						this->kinematic->normalize(q);
						this->kinematic->setPosition(q);
						
						if (this->kinematic->isValid(q))
						{
							return true;
						}
					}
					
					this->kinematic->calculateJacobian();
					
					switch (this->method)
					{
					case METHOD_DLS:
						this->kinematic->calculateJacobianInverse(0, false);
						dq = this->kinematic->getJacobianInverse() * dx;
						break;
					case METHOD_SVD:
						this->kinematic->calculateJacobianInverse(0, true);
						dq = this->kinematic->getJacobianInverse() * dx;
						break;
					case METHOD_TRANSPOSE:
						{
							::rl::math::Vector tmp = this->kinematic->getJacobian() * this->kinematic->getJacobian().transpose() * dx;
							::rl::math::Real alpha = dx.dot(tmp) / tmp.dot(tmp);
							dq = alpha * this->kinematic->getJacobian().transpose() * dx;
						}
						break;
					default:
						break;
					}
					
					this->kinematic->step(q, dq, q2);
					
					if (this->kinematic->transformedDistance(q, q2) > ::std::pow(this->delta, 2))
					{
						this->kinematic->interpolate(q, q2, this->delta, q2);
					}
					
					q = q2;
					this->kinematic->setPosition(q);
					
					remaining = ::std::chrono::duration<double>(this->getDuration() - (::std::chrono::steady_clock::now() - start)).count();
					
					if (0 == ++iteration % 100)
					{
						break;
					}
				}
				while (remaining > 0 && iteration < this->getIterations());
				
				for (::std::size_t i = 0; i < this->kinematic->getDof(); ++i)
				{
					rand(i) = this->randDistribution(this->randEngine);
				}
				
				q = this->kinematic->generatePositionUniform(rand);
				this->kinematic->setPosition(q);
				
				remaining = ::std::chrono::duration<double>(this->getDuration() - (::std::chrono::steady_clock::now() - start)).count();
			}
			while (remaining > 0 && iteration < this->getIterations());
			
			return false;
		}
Ejemplo n.º 26
0
/*
*       Do a multi-wait on the specified events.
*/
WORD ev_multi(WORD flags, MOBLK *pmo1, MOBLK *pmo2, LONG tmcount,
              LONG buparm, LONG mebuff, WORD prets[])
{
        QPB             m;
        register EVSPEC which;
        register WORD   what;
        register CQUEUE *pc;

                                                /* say nothing has      */
                                                /*   happened yet       */
        what = 0x0;
        which = 0;
                                                /* do a pre-check for a */
                                                /*   keystroke & then   */
                                                /*   clear out the forkq*/
        chkkbd();
        forker();
                                                /*   a keystroke        */
        if (flags & MU_KEYBD)
        {
                                                /* if a character is    */
                                                /*   ready then get it  */
          pc = &rlr->p_cda->c_q;
          if ( pc->c_cnt )
          {
            prets[4] = (UWORD) dq(pc);
            what |= MU_KEYBD;
          }
        }
                                                /* if we own the mouse  */
                                                /*   then do quick chks */
        if ( rlr == gl_mowner )
        {
                                                /* quick check button   */
          if (flags & MU_BUTTON)
          {
            if ( (mtrans > 1) &&
                 (downorup(pr_button, buparm)) )
            {
              what |= MU_BUTTON;
              prets[5] = pr_mclick;
            }
            else
            {
              if ( downorup(button, buparm) )
              {
                what |= MU_BUTTON;
                prets[5] = mclick;
              }
            }
          }
                                                /* quick check mouse rec*/
          if ( ( flags & MU_M1 ) &&     
               ( in_mrect(pmo1) ) )
              what |= MU_M1;
                                                /* quick check mouse rec*/
          if ( ( flags & MU_M2 ) &&
               ( in_mrect(pmo2) ) )
              what |= MU_M2;
        }
                                                /* quick check timer    */
        if (flags & MU_TIMER)
        {
          if ( tmcount == 0x0L )
            what |= MU_TIMER;
        }
                                                /* quick check message  */
        if (flags & MU_MESAG)
        {
          if ( rlr->p_qindex > 0 )
          {
            ap_rdwr(MU_MESAG, rlr, 16, mebuff);
            what |= MU_MESAG;
          }
        }
                                                /* check for quick out  */
                                                /*   if something has   */
                                                /*   already happened   */
        if (what == 0x0)
        {
                                                /* wait for a keystroke */
          if (flags & MU_KEYBD)
            iasync( MU_KEYBD, 0x0L );
                                                /* wait for a button    */
          if (flags & MU_BUTTON)
            iasync( MU_BUTTON, buparm );
                                                /* wait for mouse rect. */
          if (flags & MU_M1)
            iasync( MU_M1, ADDR(pmo1) );
                                                /* wait for mouse rect. */
          if (flags & MU_M2)
            iasync( MU_M2, ADDR(pmo2) ); 
                                                /* wait for message     */
          if (flags & MU_MESAG)
          {
            m.qpb_ppd = rlr;
            m.qpb_cnt = 16;
            m.qpb_buf = mebuff;
            iasync( MU_MESAG, ADDR(&m) );
          }
                                                /* wait for timer       */
          if (flags & MU_TIMER)
            iasync( MU_TIMER, tmcount / gl_ticktime );
                                                /* wait for events      */
          which = mwait( flags );
                                                /* cancel outstanding   */
                                                /*   events             */
          which |= acancel( flags );
        }
                                                /* get the returns      */
        ev_rets(&prets[0]);
                                                /* do aprets() if       */
                                                /*   something hasn't   */
                                                /*   already happened   */
        if (what == 0x0)
        {
          what = which;
          if (which & MU_KEYBD)
            prets[4] = apret(MU_KEYBD);
          if (which & MU_BUTTON)
            prets[5] = apret(MU_BUTTON);
          if (which & MU_M1)
            apret(MU_M1);
          if (which & MU_M2)
            apret(MU_M2);
          if (which & MU_MESAG)
            apret(MU_MESAG);
          if (which & MU_TIMER)
            apret(MU_TIMER);
        }
                                                  /* return what happened*/
        return( what );
}
Ejemplo n.º 27
0
ll solve(){
  return 1LL * N * (N - 1) / 2 - dq(1);
}
Ejemplo n.º 28
0
/*
 *  Flush the characters from a circular keyboard buffer
 */
void fq(void)
{
    while (rlr->p_cda->c_q.c_cnt)
        dq(&rlr->p_cda->c_q);
}
Ejemplo n.º 29
0
void SeniorVMHandle::q_push_imm(long n)
{
  db(HANDLE.q_push_imm.handle);
  dq(n);
}
dgFloat32 dgCollisionChamferCylinder::RayCast(const dgVector& q0, const dgVector& q1, dgFloat32 maxT, dgContactPoint& contactOut, const dgBody* const body, void* const userData, OnRayPrecastAction preFilter) const
{
	if (q0.m_x > m_height) {
		if (q1.m_x < m_height) {
			dgFloat32 t1 = (m_height - q0.m_x) / (q1.m_x - q0.m_x);
			dgFloat32 y = q0.m_y + (q1.m_y - q0.m_y) * t1;
			dgFloat32 z = q0.m_z + (q1.m_z - q0.m_z) * t1;
			if ((y * y + z * z) < m_radius * m_radius) {
				contactOut.m_normal = dgVector(dgFloat32(1.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
				//contactOut.m_userId = SetUserDataID();
				return t1;
			}
		}
	}

	if (q0.m_x < -m_height) {
		if (q1.m_x > -m_height) {
			dgFloat32 t1 = (-m_height - q0.m_x) / (q1.m_x - q0.m_x);
			dgFloat32 y = q0.m_y + (q1.m_y - q0.m_y) * t1;
			dgFloat32 z = q0.m_z + (q1.m_z - q0.m_z) * t1;
			if ((y * y + z * z) < m_radius * m_radius) {
				contactOut.m_normal = dgVector(dgFloat32(-1.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
				//contactOut.m_userId = SetUserDataID();
				return t1;
			}
		}
	}

	dgVector dq((q1 - q0) & dgVector::m_triplexMask);

	// avoid NaN as a result of a division by zero
	if ((dq % dq) <= 0.0f) {
		return dgFloat32(1.2f);
	}

	dgVector dir(dq.CompProduct4(dq.InvMagSqrt()));
	if (dgAbsf(dir.m_x) > 0.9999f) {
		return dgCollisionConvex::RayCast(q0, q1, maxT, contactOut, NULL, NULL, NULL);
	}

	dgVector q1q0 (q1 - q0);
	dgFloat32 t = -q0.m_x / q1q0.m_x;
	dgVector p0(q0 + q1q0.Scale4(t));
	if ((p0 % p0) < (m_radius + m_height)) {
		dgVector origin0(p0.CompProduct4(p0.InvMagSqrt()).Scale4(m_radius));
		dgVector origin1(origin0.CompProduct4(dgVector::m_negOne));
		dgFloat32 t0 = dgRayCastSphere(q0, q1, origin0, m_height);
		dgFloat32 t1 = dgRayCastSphere(q0, q1, origin1, m_height);
		if(t1 < t0) {
			t0 = t1;
			origin0 = origin1;
		}

		if ((t0 >= 0.0f) && (t0 <= 1.0f)) {
			contactOut.m_normal = q0 + dq.Scale4(t0) - origin0;
			dgAssert(contactOut.m_normal.m_w == dgFloat32(0.0f));
			contactOut.m_normal = contactOut.m_normal.CompProduct4(contactOut.m_normal.DotProduct4(contactOut.m_normal).InvSqrt());
			return t0;
		} else {
			q1q0.m_x = dgFloat32(0.0f);
			q1q0 = q1q0.CompProduct4(q1q0.InvMagSqrt());
			origin0 = q1q0.Scale4(-m_radius);
			t0 = dgRayCastSphere(q0, q1, origin0, m_height);
			if ((t0 >= 0.0f) && (t0 <= 1.0f)) {
				contactOut.m_normal = q0 + dq.Scale4(t0) - origin0;
				dgAssert(contactOut.m_normal.m_w == dgFloat32(0.0f));
				contactOut.m_normal = contactOut.m_normal.CompProduct4(contactOut.m_normal.DotProduct4(contactOut.m_normal).InvSqrt());
				return t0;
			}
		}
	}

	return dgFloat32(1.2f);
}