Esempio n. 1
0
/**
 * @function connectGoal
 */
bool JG_RRT::connectGoal()
{
    Eigen::MatrixXd J(3,7);
    Eigen::MatrixXd Jinv(7,3);
    Eigen::MatrixXd delta_x;
    Eigen::MatrixXd delta_q;
    Eigen::MatrixXd q_new;
    JG_RRT::StepResult result;
    double dist_new;
    double dist_old;

    result = STEP_PROGRESS;
    dist_new = 0;
    dist_old = DBL_MAX;

    int i = 0;
    while( result == STEP_PROGRESS && (dist_new < dist_old) )
    {   //-- Get the closest node to the goal ( workspace metric )
        int NNidx = pop_Ranking();
        if( NNidx == -1 )
        {
            break;
        }
        Eigen::VectorXd q_closest = configVector[NNidx];
        dist_old = wsDistance( q_closest );

        //-- Get the Jacobian
        robinaLeftArm_j( q_closest, TWBase, Tee, J );

        //-- Get the pseudo-inverse (easy way)
        pseudoInv( 3, 7, J, Jinv );

        //-- Get the workspace
        delta_x = wsDiff( q_closest );

        delta_q = Jinv*delta_x;
        //-- Scale -- with this 2 actually result will always be in PROGRESS, if not COLLISION
        double scal = 2*stepSize/delta_q.norm();
        delta_q = delta_q*scal;

        //-- Get q_new
        q_new = q_closest + delta_q;

        //-- Attempt a new step towards J
        result = tryStep( q_new, NNidx );
        i++;
        //-- Check
        if( result == STEP_PROGRESS )
        {   dist_new = wsDistance( configVector[configVector.size() - 1] );
            if( dist_new < distanceThresh )
            {
                result = STEP_REACHED;
                break;
            }
        }

    }
    return( result == STEP_REACHED );
}
Esempio n. 2
0
int IsoparametricTransformation::TransformBack(const Vector &pt,
                                               IntegrationPoint &ip)
{
   const int    max_iter = 16;
   const double  ref_tol = 1e-15;
   const double phys_tol = 1e-15*pt.Normlinf();

   const int dim = FElem->GetDim();
   const int sdim = PointMat.Height();
   const int geom = FElem->GetGeomType();
   IntegrationPoint xip, prev_xip;
   double xd[3], yd[3], dxd[3], Jid[9];
   Vector x(xd, dim), y(yd, sdim), dx(dxd, dim);
   DenseMatrix Jinv(Jid, dim, sdim);
   bool hit_bdr = false, prev_hit_bdr;

   // Use the center of the element as initial guess
   xip = Geometries.GetCenter(geom);
   xip.Get(xd, dim); // xip -> x

   for (int it = 0; it < max_iter; it++)
   {
      // Newton iteration:    x := x + J(x)^{-1} [pt-F(x)]
      // or when dim != sdim: x := x + [J^t.J]^{-1}.J^t [pt-F(x)]
      Transform(xip, y);
      subtract(pt, y, y); // y = pt-y
      if (y.Normlinf() < phys_tol) { ip = xip; return 0; }
      SetIntPoint(&xip);
      CalcInverse(Jacobian(), Jinv);
      Jinv.Mult(y, dx);
      x += dx;
      prev_xip = xip;
      prev_hit_bdr = hit_bdr;
      xip.Set(xd, dim); // x -> xip
      // If xip is ouside project it on the boundary on the line segment
      // between prev_xip and xip
      hit_bdr = !Geometry::ProjectPoint(geom, prev_xip, xip);
      if (dx.Normlinf() < ref_tol) { ip = xip; return 0; }
      if (hit_bdr)
      {
         xip.Get(xd, dim); // xip -> x
         if (prev_hit_bdr)
         {
            prev_xip.Get(dxd, dim); // prev_xip -> dx
            subtract(x, dx, dx);    // dx = xip - prev_xip
            if (dx.Normlinf() < ref_tol) { return 1; }
         }
      }
   }
   ip = xip;
   return 2;
}
Esempio n. 3
0
  virtual void compute_solution(const PhysData &inner_cell_data, const RealVectorNDIM &boundary_face_normal, RealVectorNEQS &boundary_face_solution)
  {
    enum {ENTR=0,OMEGA=1,APLUS=2,AMIN=3};


    RealMatrix J((int)NDIM,(int)NDIM);
    RealMatrix Jinv((int)NDIM,(int)NDIM);
    Real detJ;

    RealMatrix nodes;
    inner_cell->get().space->support().geometry_space().allocate_coordinates(nodes);
    inner_cell->get().space->support().geometry_space().put_coordinates(nodes,inner_cell->get().idx);
    inner_cell->get().space->support().element_type().compute_jacobian(inner_cell->get().sf->flx_pts().row(cell_flx_pt),nodes,J);
    Jinv = J.inverse();
    detJ = J.determinant();

//    Real Jxi  = Jinv.row(KSI).norm();
//    Real Jeta = Jinv.row(ETA).norm();

//    std::cout << "Jxi = " << Jxi << "    Jeta = " << Jeta << std::endl;

    outward_normal = flx_pt_plane_jacobian_normal->get().plane_unit_normal[cell_flx_pt] * flx_pt_plane_jacobian_normal->get().sf->flx_pt_sign(cell_flx_pt);

    const RealRowVector& n = outward_normal;
    RealRowVector s((int)NDIM); s << n[YY], -n[XX];

//    std::cout << "n = " << n << std::endl;
//    std::cout << "s = " << s << std::endl;

//    RealVector U0(2);
//    U0[XX] = options().value< std::vector<Real> >("U0")[XX];
//    U0[YY] = options().value< std::vector<Real> >("U0")[YY];
//    Real u0n = U0.dot(n);
//    Real u0s = U0.dot(s);

    RealRowVector mapped_n = n * detJ * Jinv;
    RealRowVector mapped_s = s * detJ * Jinv;

//    std::cout << "mapped_n = " << mapped_n << std::endl;
//    std::cout << "mapped_s = " << mapped_s << std::endl;

//    if ( std::abs(outward_normal[XX]-1.) > 1e-10)
//      throw common::BadValue(FromHere(), "outward_normal incorrect");

    for (Uint f=0; f<inner_cell->get().sf->nb_flx_pts(); ++f)
    {
      cons_to_char(cons_flx_pt_solution[f],outward_normal,char_flx_pt_solution[f]);
    }

    // Extrapolation BC
    char_bdry_solution[ENTR ] = char_flx_pt_solution[cell_flx_pt][ENTR ];
    char_bdry_solution[OMEGA] = char_flx_pt_solution[cell_flx_pt][OMEGA];
    char_bdry_solution[APLUS] = char_flx_pt_solution[cell_flx_pt][APLUS];
    char_bdry_solution[AMIN ] = char_flx_pt_solution[cell_flx_pt][AMIN ];

    sf_deriv_xi.resize(inner_cell->get().sf->nb_flx_pts());
    sf_deriv_eta.resize(inner_cell->get().sf->nb_flx_pts());
    sf_deriv_n.resize(inner_cell->get().sf->nb_flx_pts());
    sf_deriv_s.resize(inner_cell->get().sf->nb_flx_pts());
    inner_cell->get().sf->compute_flux_derivative(KSI,inner_cell->get().sf->flx_pts().row(cell_flx_pt),sf_deriv_xi);
    inner_cell->get().sf->compute_flux_derivative(ETA,inner_cell->get().sf->flx_pts().row(cell_flx_pt),sf_deriv_eta);


    for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j)
    {
      sf_deriv_n[j] = mapped_n[KSI] * sf_deriv_xi[j] + mapped_n[ETA] * sf_deriv_eta[j];
      sf_deriv_s[j] = mapped_s[KSI] * sf_deriv_xi[j] + mapped_s[ETA] * sf_deriv_eta[j];
    }

    std::vector<Real> omega(inner_cell->get().sf->nb_flx_pts());
    Real dAmindn = 0.;
    Real dAminds = 0.;
    Real dAplusdn = 0.;
    Real dAplusds = 0.;
    Real dOmegadn = 0.;
    Real dOmegads = 0.;
    Real domegadn = 0.;
    Real domegads = 0.;
    for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j)
    {
      dOmegadn   += char_flx_pt_solution[j][OMEGA] * sf_deriv_n[j];
      dOmegads   += char_flx_pt_solution[j][OMEGA] * sf_deriv_s[j];
      dAmindn    += char_flx_pt_solution[j][AMIN ] * sf_deriv_n[j];
      dAminds    += char_flx_pt_solution[j][AMIN ] * sf_deriv_s[j];
      dAplusdn   += char_flx_pt_solution[j][APLUS] * sf_deriv_n[j];
      dAplusds   += char_flx_pt_solution[j][APLUS] * sf_deriv_s[j];

      omega[j] = 0.5*(char_flx_pt_solution[j][APLUS] - char_flx_pt_solution[j][AMIN]);
      domegadn += omega[j] * sf_deriv_n[j];
      domegads += omega[j] * sf_deriv_s[j];
    }



//    dA/dn + dOmega/ds = 0
//    dAplus/dn - dAmin/dn = - 2 dOmega/ds
//    0 < (Aplus-Amin)/(Omega) < 1 --> tangent flow dominates
//    (Aplus-Amin)/(Omega) > 1 --> normal flow dominates

//    std::cout << "gradx = " << sf_deriv_xi.transpose() << std::endl;
//    std::cout << "dAmindxi_internal = " << dAmindxi_internal << std::endl;

    // Try 1
    // dAmin/dt + (u0+c0)dAmin/dn + c0 dAmin/ds - c0 dOmega/ds = 0
//    dAmindn = 1./(m_u0n-m_c0) * ( (m_u0n+m_c0)*dAmindn - 2.*m_c0*dOmegads );

    // Try 2!    dAmin/dt +  u0n dOmega/ds + u0s dAmin/dn = 0
//    dAmindn = dOmegads;

//    dAmindn = -dAplusdn  -->  dAmindn = dOmegads
//    dAmindn/dAplusdn = dAmindn/dOmegads

      // BC divzero
//      dAmindn = dAplusdn + 2*dOmegads;

     // BC dAdt + u0n dAdn = 0 boils to same as divzero when u0s=0
     // dAmindn = 1./m_c0*(u0s*dAminds+u0s*dAplusds+m_c0*dAplusdn+2*m_c0*dOmegads);

//    Aplus*Amin > 0 --> pulse
//    Aplus*Amin < 0 --> vortex

//    Aplus + Amin = 0 --> vortex
//    Aplus - Amin = 0 --> pulse
//    Aplus+Amin =
//    Real ratio = ( std::abs(dAmindn) < 1e-12 ? 0. : dAmindn/dOmegads);

//    static Real i = 0.;
//    static Real avg_ratio = ratio;
//    static Real max_ratio = ratio;
//    static Real min_ratio = ratio;


//    if (ratio != 0 && std::abs(ratio) < 2)
//    {
//      max_ratio = std::max(max_ratio,ratio);
//      min_ratio = std::min(min_ratio,ratio);

//      avg_ratio = i/(i+1.) * avg_ratio  +  1./(i+1.) * ratio;
//      ++i;
////      std::cout << "ratio = " << ratio << "\t  i = " << i << "\t  avg = " << avg_ratio << " \t  max = " << max_ratio << " \t  min = " << min_ratio << std::endl;
//    }

    // vortex: ratio = 1.    alpha = 0
    // pulse:  ratio = 0.5   alpha = 1
//    Real alpha = std::max(0., std::min(1., 2.* (1.-std::abs(ratio)) ));
//    std::cout << "alpha = " << alpha << std::endl;
    Real alpha = options().value<Real>("alpha");
    dAmindn = (1.-alpha)*dOmegads + alpha*dAmindn;

//    dAmindn = dAmindn + 2.*dAmindn/dAplusdn*dOmegads;
//    dAmindn = 0.;//dOmegads;
    // Hedstrom:  dAmin/dt = 0
    // --> (u0n - c0) dAmin/dn + u0s dAmin/ds + c0 dOmega/ds = 0
//    dAmindn = 1./(m_u0n-m_c0)*(-m_u0s*dAminds - m_c0*dOmegads);


    // dAmin/dt + u0n dAmin/dn + u0s dAmin/ds = 0
//    dAmindn = 1./(m_u0n+m_c0)*(m_u0n*dAmindn - m_c0*dOmegads);

    // Try 3
//    dAmindn = 2.*dOmegads + dAplusdn;

//    replace = dAmindxi_internal + 2.*dOmegadeta;
//    replace = -dAmindxi_internal;
//    replace = -dAplusdxi;
//    replace = dAmindxi_internal;

//    replace = 2./(m_u0n-m_c0) * ( m_u0n/2.*dAmindxi_internal  -m_c0/2.*dAplusdxi -m_c0*dOmegadeta );


//    // Also modify equation for omega:
//    dAplusdn = -dAmindn;

//    Real A = 0.5*(char_flx_pt_solution[cell_flx_pt][APLUS] + char_flx_pt_solution[cell_flx_pt][AMIN ]);

//    dAplusdn = -dAmindn;
    char_bdry_solution[AMIN ] = dAmindn;
//    char_bdry_solution[APLUS] = dAplusdn;

    for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j)
    {
      if (j!=cell_flx_pt)
      {
        char_bdry_solution[AMIN ] -= char_flx_pt_solution[j][AMIN ] * sf_deriv_n[j];
//        char_bdry_solution[APLUS] -= char_flx_pt_solution[j][APLUS] * sf_deriv_xi[j];
      }
    }
    char_bdry_solution[AMIN ] /= sf_deriv_n[cell_flx_pt];

//    Real A = 0.5*(char_flx_pt_solution[cell_flx_pt][APLUS] + char_flx_pt_solution[cell_flx_pt][AMIN]);
//    char_bdry_solution[APLUS] = 2.*A - char_bdry_solution[AMIN];
//    char_bdry_solution[APLUS] /= sf_deriv_xi[cell_flx_pt];
////    std::cout << char_bdry_solution[AMIN] << std::endl;

//    compute_optimization(char_bdry_solution[OMEGA],char_bdry_solution[APLUS],char_bdry_solution[AMIN]);

//    char_bdry_solution[APLUS] = char_flx_pt_solution[cell_flx_pt][APLUS];
//    compute_optimization_2(char_bdry_solution[OMEGA],char_bdry_solution[AMIN]);



    char_to_cons(char_bdry_solution,outward_normal,boundary_face_solution);

  }
Esempio n. 4
0
void
SSPquad::GetStab(void)
// this function computes the stabilization stiffness matrix for the element
{
	Vector g1(SSPQ_NUM_DIM);
	Vector g2(SSPQ_NUM_DIM);
	Matrix I(SSPQ_NUM_DIM,SSPQ_NUM_DIM);
	Matrix FCF(SSPQ_NUM_DIM,SSPQ_NUM_DIM);
	Matrix Jmat(SSPQ_NUM_DIM,SSPQ_NUM_DIM);
	Matrix Jinv(SSPQ_NUM_DIM,SSPQ_NUM_DIM);
	Matrix dNloc(SSPQ_NUM_NODE,SSPQ_NUM_DIM);
	Matrix dN(SSPQ_NUM_NODE,SSPQ_NUM_DIM);
	Matrix Mben(2,SSPQ_NUM_DOF);
	double Hss;
	double Hst;
	double Htt;
	
	// shape function derivatives (local crd) at center
	dNloc(0,0) = -0.25;
	dNloc(1,0) =  0.25;
	dNloc(2,0) =  0.25;
	dNloc(3,0) = -0.25;
	dNloc(0,1) = -0.25;
	dNloc(1,1) = -0.25;
	dNloc(2,1) =  0.25;
	dNloc(3,1) =  0.25;

	// jacobian matrix
	Jmat = mNodeCrd*dNloc;
	// inverse of the jacobian matrix
	Jmat.Invert(Jinv);

	// shape function derivatives (global crd)
	dN = dNloc*Jinv;

	// define hourglass stabilization vector  gamma = 0.25*(h - (h^x)*bx - (h^y)*by);
	double hx = mNodeCrd(0,0) - mNodeCrd(0,1) + mNodeCrd(0,2) - mNodeCrd(0,3);
	double hy = mNodeCrd(1,0) - mNodeCrd(1,1) + mNodeCrd(1,2) - mNodeCrd(1,3);
	double gamma[4];
	gamma[0] = 0.25*( 1.0 - hx*dN(0,0) - hy*dN(0,1));
	gamma[1] = 0.25*(-1.0 - hx*dN(1,0) - hy*dN(1,1));
	gamma[2] = 0.25*( 1.0 - hx*dN(2,0) - hy*dN(2,1));
	gamma[3] = 0.25*(-1.0 - hx*dN(3,0) - hy*dN(3,1));

	// define mapping matrices
	Mmem.Zero();
	Mben.Zero();
	for (int i = 0; i < 4; i++) {
		Mmem(0,2*i)   = dN(i,0);
		Mmem(1,2*i+1) = dN(i,1);
		Mmem(2,2*i)   = dN(i,1);
		Mmem(2,2*i+1) = dN(i,0);

		Mben(0,2*i)   = gamma[i];
		Mben(1,2*i+1) = gamma[i];
	}

	// base vectors
	g1(0) = Jmat(0,0);
	g1(1) = Jmat(1,0);
	g2(0) = Jmat(0,1);
	g2(1) = Jmat(1,1);
	// normalize base vectors
	g1.Normalize();
	g2.Normalize();
	
	// compute second moment of area tensor
	double fourThree = 4.0/3.0;
	I = fourThree*mThickness*J0*(DyadicProd(g1,g1) + DyadicProd(g2,g2));

	// stabilization terms
	Hss = (I(0,0)*Jinv(1,0)*Jinv(1,0) + I(0,1)*Jinv(0,0)*Jinv(1,0) + I(1,1)*Jinv(0,0)*Jinv(0,0))*0.25;
	Htt = (I(0,0)*Jinv(1,1)*Jinv(1,1) + I(0,1)*Jinv(0,1)*Jinv(1,1) + I(1,1)*Jinv(0,1)*Jinv(0,1))*0.25;
	Hst = (I(0,0)*Jinv(1,1)*Jinv(1,0) + I(0,1)*(Jinv(1,0)*Jinv(0,1) + Jinv(1,1)*Jinv(0,0)) + I(1,1)*Jinv(0,1)*Jinv(0,0))*0.25;

	// get material tangent
	const Matrix &CmatI = theMaterial->getInitialTangent();

	// compute stabilization matrix
	FCF(0,0) = (CmatI(0,0) - (CmatI(0,1) + CmatI(1,0)) + CmatI(1,1))*Hss;
	FCF(0,1) = (CmatI(0,1) - (CmatI(0,0) + CmatI(1,1)) + CmatI(1,0))*Hst;
	FCF(1,0) = (CmatI(1,0) - (CmatI(0,0) + CmatI(1,1)) + CmatI(0,1))*Hst;
	FCF(1,1) = (CmatI(1,1) - (CmatI(0,1) + CmatI(1,0)) + CmatI(0,0))*Htt;
	
	// compute stiffness matrix for stabilization terms
	Kstab.Zero();
	Kstab.addMatrixTripleProduct(1.0, Mben, FCF, 1.0);

	return;
}
Esempio n. 5
0
double IK::solve_ik()
{
	int i, j;
	double current_max_condnum = -1.0;
	copy_jacobian();
	if(n_all_const > 0)
	{
		////
		// check rank when HIGH_IF_POSSIBLE constraints have high priority
		int n_high_const;
		fMat Jhigh;
		fMat wJhigh;
		fVec fb_high;
		fVec weight_high;
		int* is_high_const = 0;
		double cond_number = 1.0;
//		cerr << "---" << endl;
//		cerr << n_const[HIGH_PRIORITY] << " " << n_const[HIGH_IF_POSSIBLE] << " " << n_const[LOW_PRIORITY] << endl;
		if(n_const[HIGH_IF_POSSIBLE] > 0)
		{
			is_high_const = new int [n_const[HIGH_IF_POSSIBLE]];
			// initialize
			for(i=0; i<n_const[HIGH_IF_POSSIBLE]; i++)
				is_high_const[i] = true;
			// search
			int search_phase = 0;
			while(1)
			{
				n_high_const = n_const[HIGH_PRIORITY];
				for(i=0; i<n_const[HIGH_IF_POSSIBLE]; i++)
				{
					if(is_high_const[i]) n_high_const++;
				}
				Jhigh.resize(n_high_const, n_dof);
				wJhigh.resize(n_high_const, n_dof);
				fb_high.resize(n_high_const);
				weight_high.resize(n_high_const);
				if(n_const[HIGH_PRIORITY] > 0)
				{
					// set fb and J of higher priority pins
					for(i=0; i<n_const[HIGH_PRIORITY]; i++)
					{
						fb_high(i) = fb[HIGH_PRIORITY](i);
						weight_high(i) = weight[HIGH_PRIORITY](i);
						for(j=0; j<n_dof; j++)
						{
							Jhigh(i, j) = J[HIGH_PRIORITY](i, j);
							wJhigh(i, j) = Jhigh(i, j) * weight_high(i) / joint_weights(j);
						}
					}
				}
				int count = 0;
				// set fb and J of medium priority pins
				for(i=0; i<n_const[HIGH_IF_POSSIBLE]; i++)
				{
					if(is_high_const[i])
					{
						fb_high(n_const[HIGH_PRIORITY]+count) = fb[HIGH_IF_POSSIBLE](i);
						weight_high(n_const[HIGH_PRIORITY]+count) = weight[HIGH_IF_POSSIBLE](i);
						for(j=0; j<n_dof; j++)
						{
							Jhigh(n_const[HIGH_PRIORITY]+count, j) = J[HIGH_IF_POSSIBLE](i, j);
							wJhigh(n_const[HIGH_PRIORITY]+count, j) = J[HIGH_IF_POSSIBLE](i, j) * weight[HIGH_IF_POSSIBLE](i) / joint_weights(j);
						}
						count++;
					}
				}
				// singular value decomposition
				fMat U(n_high_const, n_high_const), VT(n_dof, n_dof);
				fVec s;
				int s_size;
				if(n_high_const < n_dof) s_size = n_high_const;
				else s_size = n_dof;
				s.resize(s_size);
				wJhigh.svd(U, s, VT);
				double condnum_limit = max_condnum * 100.0;
				if(s(s_size-1) > s(0)/(max_condnum*condnum_limit))
					cond_number = s(0) / s(s_size-1);
				else
					cond_number = condnum_limit;
				if(current_max_condnum < 0.0 || cond_number > current_max_condnum)
				{
					current_max_condnum = cond_number;
				}
				if(n_high_const <= n_const[HIGH_PRIORITY]) break;
				// remove some constraints
				if(cond_number > max_condnum)
				{
					int reduced = false;
					for(i=n_constraints-1; i>=0; i--)
					{
						if(constraints[i]->enabled &&
						   constraints[i]->priority == HIGH_IF_POSSIBLE &&
						   constraints[i]->i_const >= 0 &&
						   constraints[i]->GetType() == HANDLE_CONSTRAINT &&
						   is_high_const[constraints[i]->i_const])
						{
							IKHandle* h = (IKHandle*)constraints[i];
							if(search_phase ||
							   (!search_phase && h->joint->DescendantDOF() > 0))
							{
								for(j=0; j<constraints[i]->n_const; j++)
								{
									is_high_const[constraints[i]->i_const + j] = false;
								}
								constraints[i]->is_dropped = true;
//								cerr << "r" << flush;
								reduced = true;
								break;
							}
						}
					}
					if(!reduced) search_phase++;
				}
				else break;
			}
		}
		else
		{
			n_high_const = n_const[HIGH_PRIORITY];
			Jhigh.resize(n_high_const, n_dof);
			wJhigh.resize(n_high_const, n_dof);
			fb_high.resize(n_high_const);
			weight_high.resize(n_high_const);
			if(n_high_const > 0)
			{
				Jhigh.set(J[HIGH_PRIORITY]);
				fb_high.set(fb[HIGH_PRIORITY]);
				weight_high.set(weight[HIGH_PRIORITY]);
			}
		}
#if 0
		////
		// adjust feedback according to the condition number
		if(current_max_condnum > max_condnum)
			fb_high.zero();
		else
		{
			double k = (current_max_condnum-max_condnum)/(1.0-max_condnum);
			fb_high *= k;
			cerr << current_max_condnum << ", " << k << endl;
		}
		////
		////
		if(current_max_condnum < 0.0) current_max_condnum = 1.0;
#endif
		int n_low_const = n_all_const - n_high_const;
		int low_first = 0, count = 0;
		fMat Jlow(n_low_const, n_dof);
		fVec fb_low(n_low_const);
		fVec weight_low(n_low_const);
		for(i=0; i<n_const[HIGH_IF_POSSIBLE]; i++)
		{
			if(!is_high_const[i])
			{
				fb_low(count) = fb[HIGH_IF_POSSIBLE](i);
				weight_low(count) = weight[HIGH_IF_POSSIBLE](i);
				for(j=0; j<n_dof; j++)
				{
					Jlow(count, j) = J[HIGH_IF_POSSIBLE](i, j);
				}
				count++;
			}
		}
		low_first = count;
		double* p = fb_low.data() + low_first;
		double* q = fb[LOW_PRIORITY].data();
		double* r = weight_low.data() + low_first;
		double* s = weight[LOW_PRIORITY].data();
		for(i=0; i<n_const[LOW_PRIORITY]; p++, q++, r++, s++, i++)
		{
//			fb_low(low_first+i) = fb[LOW_PRIORITY](i);
			*p = *q;
			*r = *s;
			double* a = Jlow.data() + low_first + i;
			int a_row = Jlow.row();
			double* b = J[LOW_PRIORITY].data() + i;
			int b_row = J[LOW_PRIORITY].row();
			for(j=0; j<n_dof; a+=a_row, b+=b_row, j++)
			{
//				Jlow(low_first+i, j) = J[LOW_PRIORITY](i, j);
				*a = *b;
			}
		}
		if(is_high_const) delete[] is_high_const;

		fVec jvel(n_dof);   // ³û¼â1¡¦x
		fVec jvel0(n_dof);  // ¹ó/¡¦¾å
		fVec fb_low_0(n_low_const), dfb(n_low_const), y(n_dof);
		fMat Jinv(n_dof, n_high_const), W(n_dof, n_dof), JW(n_low_const, n_dof);
		fVec w_error(n_low_const), w_norm(n_dof);
		// weighted
		double damping = 0.1;
//		w_error = 1.0;
		w_error.set(weight_low);
		w_norm = 1.0;
//		w_norm.set(joint_weights);
//		cerr << "joint_weights = " << joint_weights << endl;
//		cerr << "weight_high = " << weight_high << endl;
//		cerr << "weight_low = " << weight_low << endl;
#ifdef MEASURE_TIME
		clock_t t1 = clock();
#endif
		// ¹ó/¡¦¾å¡¦€ÅæéòÉçïàïêvZ
		if(n_high_const > 0)
		{
			for(i=0; i<n_dof; i++)
			{
				int a_row = wJhigh.row();
				double* a = wJhigh.data() + a_row*i;
				int b_row = Jhigh.row();
				double* b = Jhigh.data() + b_row*i;
				double* c = joint_weights.data() + i;
				double* d = weight_high.data();
				for(j=0; j<n_high_const; a++, b++, d++, j++)
				{
//					wJhigh(j, i) = Jhigh(j, i) / joint_weights(i);
					*a = *b * *d / *c;
				}
			}
			fVec w_fb_high(fb_high);
			for(i=0; i<n_high_const; i++)
				w_fb_high(i) *= weight_high(i);
			Jinv.p_inv(wJhigh);
			jvel0.mul(Jinv, w_fb_high);
			W.mul(Jinv, wJhigh);
			for(i=0; i<n_dof; i++)
			{
				double* w = W.data() + i;
				double a = joint_weights(i);
				for(j=0; j<n_dof; w+=n_dof, j++)
				{
					if(i==j) *w -= 1.0;
					*w /= -a;
				}
				jvel0(i) /= a;
			}
			JW.mul(Jlow, W);
		}
		else
		{
			jvel0.zero();
			JW.set(Jlow);
		}
#ifdef MEASURE_TIME
		clock_t t2 = clock();
		high_constraint_time += (double)(t2-t1)/(double)CLOCKS_PER_SEC;
#endif
		// Ǥ¡¦#x¥¯¥È¥ë¹à¤ê³×Z
		if(n_low_const > 0)
		{
			fb_low_0.mul(Jlow, jvel0);
			dfb.sub(fb_low, fb_low_0);
			y.lineq_sr(JW, w_error, w_norm, damping, dfb);
			if(n_high_const > 0) jvel.mul(W, y);
			else jvel.set(y);
//			fVec error(n_low_const);
//			error = dfb-Jlow*jvel;
//			cerr << dfb*dfb << "->" << error*error << endl;
		}
		else
		{
			jvel.zero();
		}
		// ³û¼â1¡¦x
		jvel += jvel0;
#ifdef MEASURE_TIME
		clock_t t3 = clock();
		low_constraint_time += (double)(t3-t2)/(double)CLOCKS_PER_SEC;
#endif
		SetJointVel(jvel);
//		cerr << fb_high - Jhigh * jvel << endl;
	}
	if(current_max_condnum < 0.0) current_max_condnum = 1.0;
	return current_max_condnum;
}