Raw File
LLC.cpp
#include "LLC.h"
#include "IKOptimization.h"
#include "MuscleOptimization.h"
#include "IntegratedWorld.h"
#include "MusculoSkeletalSystem.h"
#include "Ball.h"
// #include "FSM/Machine.h"

using namespace FEM;
using namespace dart::dynamics;
using namespace dart::simulation;
using namespace Ipopt;

LowLevelController::
LowLevelController(const std::shared_ptr<IntegratedWorld>& iw)
	:mIntegratedWorld(iw)
{
	dart::math::seedRand();
	int dof = mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton()->getNumDofs();
	double k = 500;

	mKp = Eigen::VectorXd::Constant(dof,k);
	mKv = Eigen::VectorXd::Constant(dof,2*sqrt(k));
	mKjt = Eigen::VectorXd::Constant(dof,0.1);
	for(int i =0;i<6;i++)
	{
		mKp[dof-1-i] = 2.0*mKp[dof-1-i];	
		mKv[dof-1-i] = sqrt(2.0)*mKv[dof-1-i];
	}
	
	mTargetPositions = Eigen::VectorXd::Constant(dof,0.0);
	mTargetVelocities = Eigen::VectorXd::Constant(dof,0.0);

#ifdef USE_MUSCLE
	mMuscleOptimization = new MuscleOptimization(mIntegratedWorld);
	mMuscleOptimizationSolver = new IpoptApplication();
	
	// mMuscleOptimizationSolver->Options()->SetStringValue("mu_strategy", "adaptive");
	mMuscleOptimizationSolver->Options()->SetStringValue("jac_c_constant", "yes");
	mMuscleOptimizationSolver->Options()->SetStringValue("hessian_constant", "yes");
	// mMuscleOptimizationSolver->Options()->SetStringValue("mehrotra_algorithm", "yes");
	mMuscleOptimizationSolver->Options()->SetIntegerValue("print_level", 2);
	mMuscleOptimizationSolver->Options()->SetIntegerValue("max_iter", 100);
	mMuscleOptimizationSolver->Options()->SetNumericValue("tol", 1e-2);

	mMuscleOptimizationSolver->Initialize();
	mMuscleOptimizationSolver->OptimizeTNLP(mMuscleOptimization);
#endif
}
void
LowLevelController::
SetKp(double kp)
{
	int dof = mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton()->getNumDofs();
	mKp = Eigen::VectorXd::Constant(dof,kp);
	mKv = Eigen::VectorXd::Constant(dof,2*sqrt(kp));
	mKjt = Eigen::VectorXd::Constant(dof,0.1);
	for(int i =0;i<6;i++)
	{
		mKp[dof-1-i] = 2.0*mKp[dof-1-i];	
		mKv[dof-1-i] = sqrt(2.0)*mKv[dof-1-i];
	}
	
}
Eigen::VectorXd
LowLevelController::
Solve(const Eigen::VectorXd& p_d,const Eigen::VectorXd& v_d)
{
	Eigen::VectorXd u;
	mTargetPositions = p_d;
	mTargetVelocities = v_d;
	
#ifdef USE_MUSCLE
	mIntegratedWorld->GetMusculoSkeletalSystem()->TransformAttachmentPoints();
	mIntegratedWorld->GetSoftWorld()->TimeStepping(false);
	u = ComputeActivationLevels(ComputePDForces());
#else
	u = ComputePDForces();
#endif
	return u;
}
Eigen::VectorXd
LowLevelController::
ComputePDForces()
{
	auto& skel =mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton();

	Eigen::VectorXd pos_m = mTargetPositions;
	Eigen::VectorXd vel_m = mTargetVelocities;

	Eigen::VectorXd pos = skel->getPositions();
	Eigen::VectorXd vel = skel->getVelocities();

	Eigen::VectorXd pos_diff(pos.rows());

	pos_diff = skel->getPositionDifferences(pos_m,pos);
	for(int i = 0;i<pos_diff.rows();i++)
			pos_diff[i] = dart::math::wrapToPi(pos_diff[i]);
	double time_step = mIntegratedWorld->GetRigidWorld()->getTimeStep();
	Eigen::Vector6d F_b_r = skel->getBodyNode("HandR")->getConstraintImpulse()*(1.0/time_step);
	Eigen::Vector6d F_b_l = skel->getBodyNode("HandL")->getConstraintImpulse()*(1.0/time_step);
	Eigen::VectorXd jaco_t_r = skel->getInvMassMatrix()*(skel->getJacobian(skel->getBodyNode("HandR"),Eigen::Vector3d(0,0,0)).transpose()*F_b_r);
	Eigen::VectorXd jaco_t_l = skel->getInvMassMatrix()*(skel->getJacobian(skel->getBodyNode("HandL"),Eigen::Vector3d(0,0,0)).transpose()*F_b_l);   
	
	Eigen::VectorXd qdd_desired = pos_diff.cwiseProduct(mKp) + (mTargetVelocities - skel->getVelocities()).cwiseProduct(mKv);//- jaco_t_l.cwiseProduct(mKjt) - jaco_t_r.cwiseProduct(mKjt);
				
	return qdd_desired;
}
#ifdef USE_MUSCLE
Eigen::VectorXd
LowLevelController::
ComputeActivationLevels(const Eigen::VectorXd& qdd_desired)
{
	auto& skel =mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton();

	static_cast<MuscleOptimization*>(GetRawPtr(mMuscleOptimization))->Update(qdd_desired);

	mMuscleOptimizationSolver->ReOptimizeTNLP(mMuscleOptimization);	

	Eigen::VectorXd solution =  static_cast<MuscleOptimization*>(GetRawPtr(mMuscleOptimization))->GetSolution();
	Eigen::VectorXd qdd = solution.head(skel->getNumDofs());
	Eigen::VectorXd activation = solution.tail(mIntegratedWorld->GetMusculoSkeletalSystem()->GetNumMuscles());
	// std::cout<<(qdd-qdd_desired).norm()<<std::endl;
	
	// mIntegratedWorld->GetMusculoSkeletalSystem()->SetActivationLevels(activation);
	// mIntegratedWorld->GetMusculoSkeletalSystem()->TransformAttachmentPoints();
	// mIntegratedWorld->GetSoftWorld()->TimeStepping(false);
	// mIntegratedWorld->GetMusculoSkeletalSystem()->ApplyForcesToSkeletons(mIntegratedWorld->GetSoftWorld());
	// mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton()->computeForwardDynamics();
	// std::cout<<mIntegratedWorld->GetMusculoSkeletalSystem()->GetSkeleton()->getAccelerations().transpose()<<std::endl;
	// std::cout<<qdd.transpose()<<std::endl;
	// std::cout<<std::endl;
	return activation;
}
#endif
back to top