Stabilizer.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00010 #include <rtm/CorbaNaming.h>
00011 #include <hrpModel/Link.h>
00012 #include <hrpModel/Sensor.h>
00013 #include <hrpModel/ModelLoaderUtil.h>
00014 #include "Stabilizer.h"
00015 #include "hrpsys/util/VectorConvert.h"
00016 #include <math.h>
00017 #include <boost/lambda/lambda.hpp>
00018 
00019 typedef coil::Guard<coil::Mutex> Guard;
00020 
00021 #ifndef deg2rad
00022 #define deg2rad(x) ((x) * M_PI / 180.0)
00023 #endif
00024 #ifndef rad2deg
00025 #define rad2deg(rad) (rad * 180 / M_PI)
00026 #endif
00027 
00028 // Module specification
00029 // <rtc-template block="module_spec">
00030 static const char* stabilizer_spec[] =
00031   {
00032     "implementation_id", "Stabilizer",
00033     "type_name",         "Stabilizer",
00034     "description",       "stabilizer",
00035     "version",           HRPSYS_PACKAGE_VERSION,
00036     "vendor",            "AIST",
00037     "category",          "example",
00038     "activity_type",     "DataFlowComponent",
00039     "max_instance",      "10",
00040     "language",          "C++",
00041     "lang_type",         "compile",
00042     // Configuration variables
00043     "conf.default.debugLevel", "0",
00044     ""
00045   };
00046 // </rtc-template>
00047 
00048 static std::ostream& operator<<(std::ostream& os, const struct RTC::Time &tm)
00049 {
00050     int pre = os.precision();
00051     os.setf(std::ios::fixed);
00052     os << std::setprecision(6)
00053        << (tm.sec + tm.nsec/1e9)
00054        << std::setprecision(pre);
00055     os.unsetf(std::ios::fixed);
00056     return os;
00057 }
00058 
00059 static double switching_inpact_absorber(double force, double lower_th, double upper_th);
00060 
00061 Stabilizer::Stabilizer(RTC::Manager* manager)
00062   : RTC::DataFlowComponentBase(manager),
00063     // <rtc-template block="initializer">
00064     m_qCurrentIn("qCurrent", m_qCurrent),
00065     m_qRefIn("qRef", m_qRef),
00066     m_rpyIn("rpy", m_rpy),
00067     m_zmpRefIn("zmpRef", m_zmpRef),
00068     m_StabilizerServicePort("StabilizerService"),
00069     m_basePosIn("basePosIn", m_basePos),
00070     m_baseRpyIn("baseRpyIn", m_baseRpy),
00071     m_contactStatesIn("contactStates", m_contactStates),
00072     m_toeheelRatioIn("toeheelRatio", m_toeheelRatio),
00073     m_controlSwingSupportTimeIn("controlSwingSupportTime", m_controlSwingSupportTime),
00074     m_qRefSeqIn("qRefSeq", m_qRefSeq),
00075     m_walkingStatesIn("walkingStates", m_walkingStates),
00076     m_sbpCogOffsetIn("sbpCogOffset", m_sbpCogOffset),
00077     m_qRefOut("q", m_qRef),
00078     m_tauOut("tau", m_tau),
00079     m_zmpOut("zmp", m_zmp),
00080     m_refCPOut("refCapturePoint", m_refCP),
00081     m_actCPOut("actCapturePoint", m_actCP),
00082     m_diffCPOut("diffCapturePoint", m_diffCP),
00083     m_diffFootOriginExtMomentOut("diffFootOriginExtMoment", m_diffFootOriginExtMoment),
00084     m_actContactStatesOut("actContactStates", m_actContactStates),
00085     m_COPInfoOut("COPInfo", m_COPInfo),
00086     m_emergencySignalOut("emergencySignal", m_emergencySignal),
00087     // for debug output
00088     m_originRefZmpOut("originRefZmp", m_originRefZmp),
00089     m_originRefCogOut("originRefCog", m_originRefCog),
00090     m_originRefCogVelOut("originRefCogVel", m_originRefCogVel),
00091     m_originNewZmpOut("originNewZmp", m_originNewZmp),
00092     m_originActZmpOut("originActZmp", m_originActZmp),
00093     m_originActCogOut("originActCog", m_originActCog),
00094     m_originActCogVelOut("originActCogVel", m_originActCogVel),
00095     m_actBaseRpyOut("actBaseRpy", m_actBaseRpy),
00096     m_currentBasePosOut("currentBasePos", m_currentBasePos),
00097     m_currentBaseRpyOut("currentBaseRpy", m_currentBaseRpy),
00098     m_allRefWrenchOut("allRefWrench", m_allRefWrench),
00099     m_allEECompOut("allEEComp", m_allEEComp),
00100     m_debugDataOut("debugData", m_debugData),
00101     control_mode(MODE_IDLE),
00102     st_algorithm(OpenHRP::StabilizerService::TPCC),
00103     emergency_check_mode(OpenHRP::StabilizerService::NO_CHECK),
00104     szd(NULL),
00105     // </rtc-template>
00106     m_debugLevel(0)
00107 {
00108   m_service0.stabilizer(this);
00109 }
00110 
00111 Stabilizer::~Stabilizer()
00112 {
00113 }
00114 
00115 RTC::ReturnCode_t Stabilizer::onInitialize()
00116 {
00117   std::cerr << "[" << m_profile.instance_name << "] onInitialize()" << std::endl;
00118   // <rtc-template block="bind_config">
00119   // Bind variables and configuration variable
00120   bindParameter("debugLevel", m_debugLevel, "0");
00121   
00122   // </rtc-template>
00123 
00124   // Registration: InPort/OutPort/Service
00125   // <rtc-template block="registration">
00126   // Set InPort buffers
00127   addInPort("qCurrent", m_qCurrentIn);
00128   addInPort("qRef", m_qRefIn);
00129   addInPort("rpy", m_rpyIn);
00130   addInPort("zmpRef", m_zmpRefIn);
00131   addInPort("basePosIn", m_basePosIn);
00132   addInPort("baseRpyIn", m_baseRpyIn);
00133   addInPort("contactStates", m_contactStatesIn);
00134   addInPort("toeheelRatio", m_toeheelRatioIn);
00135   addInPort("controlSwingSupportTime", m_controlSwingSupportTimeIn);
00136   addInPort("qRefSeq", m_qRefSeqIn);
00137   addInPort("walkingStates", m_walkingStatesIn);
00138   addInPort("sbpCogOffset", m_sbpCogOffsetIn);
00139 
00140   // Set OutPort buffer
00141   addOutPort("q", m_qRefOut);
00142   addOutPort("tau", m_tauOut);
00143   addOutPort("zmp", m_zmpOut);
00144   addOutPort("refCapturePoint", m_refCPOut);
00145   addOutPort("actCapturePoint", m_actCPOut);
00146   addOutPort("diffCapturePoint", m_diffCPOut);
00147   addOutPort("diffStaticBalancePointOffset", m_diffFootOriginExtMomentOut);
00148   addOutPort("actContactStates", m_actContactStatesOut);
00149   addOutPort("COPInfo", m_COPInfoOut);
00150   addOutPort("emergencySignal", m_emergencySignalOut);
00151   // for debug output
00152   addOutPort("originRefZmp", m_originRefZmpOut);
00153   addOutPort("originRefCog", m_originRefCogOut);
00154   addOutPort("originRefCogVel", m_originRefCogVelOut);
00155   addOutPort("originNewZmp", m_originNewZmpOut);
00156   addOutPort("originActZmp", m_originActZmpOut);
00157   addOutPort("originActCog", m_originActCogOut);
00158   addOutPort("originActCogVel", m_originActCogVelOut);
00159   addOutPort("actBaseRpy", m_actBaseRpyOut);
00160   addOutPort("currentBasePos", m_currentBasePosOut);
00161   addOutPort("currentBaseRpy", m_currentBaseRpyOut);
00162   addOutPort("allRefWrench", m_allRefWrenchOut);
00163   addOutPort("allEEComp", m_allEECompOut);
00164   addOutPort("debugData", m_debugDataOut);
00165   
00166   // Set service provider to Ports
00167   m_StabilizerServicePort.registerProvider("service0", "StabilizerService", m_service0);
00168   
00169   // Set service consumers to Ports
00170   
00171   // Set CORBA Service Ports
00172   addPort(m_StabilizerServicePort);
00173   
00174   // </rtc-template>
00175   RTC::Properties& prop = getProperties();
00176   coil::stringTo(dt, prop["dt"].c_str());
00177 
00178   // parameters for corba
00179   RTC::Manager& rtcManager = RTC::Manager::instance();
00180   std::string nameServer = rtcManager.getConfig()["corba.nameservers"];
00181   int comPos = nameServer.find(",");
00182   if (comPos < 0){
00183     comPos = nameServer.length();
00184   }
00185   nameServer = nameServer.substr(0, comPos);
00186   RTC::CorbaNaming naming(rtcManager.getORB(), nameServer.c_str());
00187 
00188   // parameters for internal robot model
00189   m_robot = hrp::BodyPtr(new hrp::Body());
00190   if (!loadBodyFromModelLoader(m_robot, prop["model"].c_str(), 
00191                                CosNaming::NamingContext::_duplicate(naming.getRootContext())
00192                                )){
00193     std::cerr << "[" << m_profile.instance_name << "]failed to load model[" << prop["model"] << "]" << std::endl;
00194     return RTC::RTC_ERROR;
00195   }
00196 
00197   // Setting for wrench data ports (real + virtual)
00198   std::vector<std::string> force_sensor_names;
00199 
00200   // Find names for real force sensors
00201   int npforce = m_robot->numSensors(hrp::Sensor::FORCE);
00202   for (unsigned int i=0; i<npforce; ++i) {
00203       force_sensor_names.push_back(m_robot->sensor(hrp::Sensor::FORCE, i)->name);
00204   }
00205 
00206   // load virtual force sensors
00207   readVirtualForceSensorParamFromProperties(m_vfs, m_robot, prop["virtual_force_sensor"], std::string(m_profile.instance_name));
00208   int nvforce = m_vfs.size();
00209   for (unsigned int i=0; i<nvforce; ++i) {
00210       for ( std::map<std::string, hrp::VirtualForceSensorParam>::iterator it = m_vfs.begin(); it != m_vfs.end(); it++ ) {
00211           if (it->second.id == i) {
00212               force_sensor_names.push_back(it->first);
00213           }
00214       }
00215   }
00216 
00217   int nforce = npforce + nvforce;
00218   m_wrenches.resize(nforce);
00219   m_wrenchesIn.resize(nforce);
00220   m_ref_wrenches.resize(nforce);
00221   m_ref_wrenchesIn.resize(nforce);
00222   m_limbCOPOffset.resize(nforce);
00223   m_limbCOPOffsetIn.resize(nforce);
00224   std::cerr << "[" << m_profile.instance_name << "] force sensor ports (" << npforce << ")" << std::endl;
00225   for (unsigned int i=0; i<nforce; ++i) {
00226       std::string force_sensor_name = force_sensor_names[i];
00227       // actual inport
00228       m_wrenchesIn[i] = new RTC::InPort<RTC::TimedDoubleSeq>(force_sensor_name.c_str(), m_wrenches[i]);
00229       m_wrenches[i].data.length(6);
00230       registerInPort(force_sensor_name.c_str(), *m_wrenchesIn[i]);
00231       // referecen inport
00232       m_ref_wrenchesIn[i] = new RTC::InPort<RTC::TimedDoubleSeq>(std::string(force_sensor_name+"Ref").c_str(), m_ref_wrenches[i]);
00233       m_ref_wrenches[i].data.length(6);
00234       registerInPort(std::string(force_sensor_name+"Ref").c_str(), *m_ref_wrenchesIn[i]);
00235       std::cerr << "[" << m_profile.instance_name << "]   name = " << force_sensor_name << std::endl;
00236   }
00237   std::cerr << "[" << m_profile.instance_name << "] limbCOPOffset ports (" << npforce << ")" << std::endl;
00238   for (unsigned int i=0; i<nforce; ++i) {
00239       std::string force_sensor_name = force_sensor_names[i];
00240       std::string nm("limbCOPOffset_"+force_sensor_name);
00241       m_limbCOPOffsetIn[i] = new RTC::InPort<RTC::TimedPoint3D>(nm.c_str(), m_limbCOPOffset[i]);
00242       registerInPort(nm.c_str(), *m_limbCOPOffsetIn[i]);
00243       std::cerr << "[" << m_profile.instance_name << "]   name = " << nm << std::endl;
00244   }
00245 
00246   // setting from conf file
00247   // rleg,TARGET_LINK,BASE_LINK,x,y,z,rx,ry,rz,rth #<=pos + rot (axis+angle)
00248   coil::vstring end_effectors_str = coil::split(prop["end_effectors"], ",");
00249   if (end_effectors_str.size() > 0) {
00250     size_t prop_num = 10;
00251     size_t num = end_effectors_str.size()/prop_num;
00252     for (size_t i = 0; i < num; i++) {
00253       std::string ee_name, ee_target, ee_base;
00254       coil::stringTo(ee_name, end_effectors_str[i*prop_num].c_str());
00255       coil::stringTo(ee_target, end_effectors_str[i*prop_num+1].c_str());
00256       coil::stringTo(ee_base, end_effectors_str[i*prop_num+2].c_str());
00257       STIKParam ikp;
00258       for (size_t j = 0; j < 3; j++) {
00259         coil::stringTo(ikp.localp(j), end_effectors_str[i*prop_num+3+j].c_str());
00260       }
00261       double tmpv[4];
00262       for (int j = 0; j < 4; j++ ) {
00263         coil::stringTo(tmpv[j], end_effectors_str[i*prop_num+6+j].c_str());
00264       }
00265       ikp.localR = Eigen::AngleAxis<double>(tmpv[3], hrp::Vector3(tmpv[0], tmpv[1], tmpv[2])).toRotationMatrix(); // rotation in VRML is represented by axis + angle
00266       ikp.target_name = ee_target;
00267       ikp.ee_name = ee_name;
00268       {
00269           bool is_ee_exists = false;
00270           for (size_t j = 0; j < npforce; j++) {
00271               hrp::Sensor* sensor = m_robot->sensor(hrp::Sensor::FORCE, j);
00272               hrp::Link* alink = m_robot->link(ikp.target_name);
00273               while (alink != NULL && alink->name != ee_base && !is_ee_exists) {
00274                   if ( alink->name == sensor->link->name ) {
00275                       is_ee_exists = true;
00276                       ikp.sensor_name = sensor->name;
00277                   }
00278                   alink = alink->parent;
00279               }
00280           }
00281       }
00282       ikp.avoid_gain = 0.001;
00283       ikp.reference_gain = 0.01;
00284       ikp.ik_loop_count = 3;
00285       // For swing ee modification
00286       ikp.target_ee_diff_p = hrp::Vector3::Zero();
00287       ikp.target_ee_diff_r = hrp::Matrix33::Identity();
00288       ikp.d_rpy_swing = hrp::Vector3::Zero();
00289       ikp.d_pos_swing = hrp::Vector3::Zero();
00290       ikp.target_ee_diff_p_filter = boost::shared_ptr<FirstOrderLowPassFilter<hrp::Vector3> >(new FirstOrderLowPassFilter<hrp::Vector3>(50.0, dt, hrp::Vector3::Zero())); // [Hz]
00291       ikp.target_ee_diff_r_filter = boost::shared_ptr<FirstOrderLowPassFilter<hrp::Vector3> >(new FirstOrderLowPassFilter<hrp::Vector3>(50.0, dt, hrp::Vector3::Zero())); // [Hz]
00292       ikp.prev_d_pos_swing = hrp::Vector3::Zero();
00293       ikp.prev_d_rpy_swing = hrp::Vector3::Zero();
00294       //
00295       stikp.push_back(ikp);
00296       jpe_v.push_back(hrp::JointPathExPtr(new hrp::JointPathEx(m_robot, m_robot->link(ee_base), m_robot->link(ee_target), dt, false, std::string(m_profile.instance_name))));
00297       // Fix for toe joint
00298       if (ee_name.find("leg") != std::string::npos && jpe_v.back()->numJoints() == 7) { // leg and has 7dof joint (6dof leg +1dof toe)
00299           std::vector<double> optw;
00300           for (int j = 0; j < jpe_v.back()->numJoints(); j++ ) {
00301               if ( j == jpe_v.back()->numJoints()-1 ) optw.push_back(0.0);
00302               else optw.push_back(1.0);
00303           }
00304           jpe_v.back()->setOptionalWeightVector(optw);
00305       }
00306       target_ee_p.push_back(hrp::Vector3::Zero());
00307       target_ee_R.push_back(hrp::Matrix33::Identity());
00308       act_ee_p.push_back(hrp::Vector3::Zero());
00309       act_ee_R.push_back(hrp::Matrix33::Identity());
00310       projected_normal.push_back(hrp::Vector3::Zero());
00311       act_force.push_back(hrp::Vector3::Zero());
00312       ref_force.push_back(hrp::Vector3::Zero());
00313       ref_moment.push_back(hrp::Vector3::Zero());
00314       contact_states_index_map.insert(std::pair<std::string, size_t>(ee_name, i));
00315       is_ik_enable.push_back( (ee_name.find("leg") != std::string::npos ? true : false) ); // Hands ik => disabled, feet ik => enabled, by default
00316       is_feedback_control_enable.push_back( (ee_name.find("leg") != std::string::npos ? true : false) ); // Hands feedback control => disabled, feet feedback control => enabled, by default
00317       is_zmp_calc_enable.push_back( (ee_name.find("leg") != std::string::npos ? true : false) ); // To zmp calculation, hands are disabled and feet are enabled, by default
00318       std::cerr << "[" << m_profile.instance_name << "] End Effector [" << ee_name << "]" << std::endl;
00319       std::cerr << "[" << m_profile.instance_name << "]   target = " << m_robot->link(ikp.target_name)->name << ", base = " << ee_base << ", sensor_name = " << ikp.sensor_name << std::endl;
00320       std::cerr << "[" << m_profile.instance_name << "]   offset_pos = " << ikp.localp.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[m]" << std::endl;
00321       prev_act_force_z.push_back(0.0);
00322     }
00323     m_contactStates.data.length(num);
00324     m_toeheelRatio.data.length(num);
00325     m_will_fall_counter.resize(num);
00326   }
00327 
00328   std::vector<std::pair<hrp::Link*, hrp::Link*> > interlocking_joints;
00329   readInterlockingJointsParamFromProperties(interlocking_joints, m_robot, prop["interlocking_joints"], std::string(m_profile.instance_name));
00330   if (interlocking_joints.size() > 0) {
00331       for (size_t i = 0; i < jpe_v.size(); i++) {
00332           std::cerr << "[" << m_profile.instance_name << "] Interlocking Joints for [" << stikp[i].ee_name << "]" << std::endl;
00333           jpe_v[i]->setInterlockingJointPairIndices(interlocking_joints, std::string(m_profile.instance_name));
00334       }
00335   }
00336 
00337 
00338   // parameters for TPCC
00339   act_zmp = hrp::Vector3::Zero();
00340   for (int i = 0; i < 2; i++) {
00341     k_tpcc_p[i] = 0.2;
00342     k_tpcc_x[i] = 4.0;
00343     k_brot_p[i] = 0.1;
00344     k_brot_tc[i] = 1.5;
00345   }
00346   // parameters for EEFM
00347   double k_ratio = 0.9;
00348   for (int i = 0; i < 2; i++) {
00349     eefm_k1[i] = -1.41429*k_ratio;
00350     eefm_k2[i] = -0.404082*k_ratio;
00351     eefm_k3[i] = -0.18*k_ratio;
00352     eefm_body_attitude_control_gain[i] = 0.5;
00353     eefm_body_attitude_control_time_const[i] = 1e5;
00354   }
00355   for (size_t i = 0; i < stikp.size(); i++) {
00356       STIKParam& ikp = stikp[i];
00357       hrp::Link* root = m_robot->link(ikp.target_name);
00358       ikp.eefm_rot_damping_gain = hrp::Vector3(20*5, 20*5, 1e5);
00359       ikp.eefm_rot_time_const = hrp::Vector3(1.5, 1.5, 1.5);
00360       ikp.eefm_rot_compensation_limit = deg2rad(10.0);
00361       ikp.eefm_swing_rot_spring_gain = hrp::Vector3(0.0, 0.0, 0.0);
00362       ikp.eefm_swing_rot_time_const = hrp::Vector3(1.5, 1.5, 1.5);
00363       ikp.eefm_pos_damping_gain = hrp::Vector3(3500*10, 3500*10, 3500);
00364       ikp.eefm_pos_time_const_support = hrp::Vector3(1.5, 1.5, 1.5);
00365       ikp.eefm_pos_compensation_limit = 0.025;
00366       ikp.eefm_swing_pos_spring_gain = hrp::Vector3(0.0, 0.0, 0.0);
00367       ikp.eefm_swing_pos_time_const = hrp::Vector3(1.5, 1.5, 1.5);
00368       ikp.eefm_ee_moment_limit = hrp::Vector3(1e4, 1e4, 1e4); // Default limit [Nm] is too large. Same as no limit.
00369       if (ikp.ee_name.find("leg") == std::string::npos) { // Arm default
00370           ikp.eefm_ee_forcemoment_distribution_weight = Eigen::Matrix<double, 6,1>::Zero();
00371       } else { // Leg default
00372           for (size_t j = 0; j < 3; j++) {
00373               ikp.eefm_ee_forcemoment_distribution_weight[j] = 1; // Force
00374               ikp.eefm_ee_forcemoment_distribution_weight[j+3] = 1e-2; // Moment
00375           }
00376       }
00377       ikp.max_limb_length = 0.0;
00378       while (!root->isRoot()) {
00379         ikp.max_limb_length += root->b.norm();
00380         ikp.parent_name = root->name;
00381         root = root->parent;
00382       }
00383       ikp.limb_length_margin = 0.13;
00384       ikp.support_time = 0.0;
00385   }
00386   eefm_swing_rot_damping_gain = hrp::Vector3(20*5, 20*5, 1e5);
00387   eefm_swing_pos_damping_gain = hrp::Vector3(33600, 33600, 7000);
00388   eefm_pos_time_const_swing = 0.08;
00389   eefm_pos_transition_time = 0.01;
00390   eefm_pos_margin_time = 0.02;
00391   eefm_zmp_delay_time_const[0] = eefm_zmp_delay_time_const[1] = 0.055;
00392   //eefm_leg_inside_margin = 0.065; // [m]
00393   //eefm_leg_front_margin = 0.05;
00394   //eefm_leg_rear_margin = 0.05;
00395   //fm_wrench_alpha_blending = 1.0; // fz_alpha
00396   eefm_gravitational_acceleration = 9.80665; // [m/s^2]
00397   cop_check_margin = 20.0*1e-3; // [m]
00398   cp_check_margin.resize(4, 30*1e-3); // [m]
00399   cp_offset = hrp::Vector3(0.0, 0.0, 0.0); // [m]
00400   tilt_margin.resize(2, 30 * M_PI / 180); // [rad]
00401   contact_decision_threshold = 50; // [N]
00402   eefm_use_force_difference_control = true;
00403   eefm_use_swing_damping = false;
00404   eefm_swing_damping_force_thre.resize(3, 300);
00405   eefm_swing_damping_moment_thre.resize(3, 15);
00406   initial_cp_too_large_error = true;
00407   is_walking = false;
00408   is_estop_while_walking = false;
00409   sbp_cog_offset = hrp::Vector3(0.0, 0.0, 0.0);
00410   use_limb_stretch_avoidance = false;
00411   use_zmp_truncation = false;
00412   limb_stretch_avoidance_time_const = 1.5;
00413   limb_stretch_avoidance_vlimit[0] = -100 * 1e-3 * dt; // lower limit
00414   limb_stretch_avoidance_vlimit[1] = 50 * 1e-3 * dt; // upper limit
00415   root_rot_compensation_limit[0] = root_rot_compensation_limit[1] = deg2rad(90.0);
00416   detection_count_to_air = static_cast<int>(0.0 / dt);
00417 
00418   // parameters for RUNST
00419   double ke = 0, tc = 0;
00420   for (int i = 0; i < 2; i++) {
00421     m_tau_x[i].setup(ke, tc, dt);
00422     m_tau_x[i].setErrorPrefix(std::string(m_profile.instance_name));
00423     m_tau_y[i].setup(ke, tc, dt);
00424     m_tau_y[i].setErrorPrefix(std::string(m_profile.instance_name));
00425     m_f_z.setup(ke, tc, dt);
00426     m_f_z.setErrorPrefix(std::string(m_profile.instance_name));
00427   }
00428   pangx_ref = pangy_ref = pangx = pangy = 0;
00429   rdx = rdy = rx = ry = 0;
00430   pdr = hrp::Vector3::Zero();
00431 
00432   // Check is legged robot or not
00433   is_legged_robot = false;
00434   for (size_t i = 0; i < stikp.size(); i++) {
00435       if (stikp[i].ee_name.find("leg") == std::string::npos) continue;
00436       hrp::Sensor* sen= m_robot->sensor<hrp::ForceSensor>(stikp[i].sensor_name);
00437       if ( sen != NULL ) is_legged_robot = true;
00438   }
00439   is_emergency = false;
00440   reset_emergency_flag = false;
00441 
00442   m_qCurrent.data.length(m_robot->numJoints());
00443   m_qRef.data.length(m_robot->numJoints());
00444   m_tau.data.length(m_robot->numJoints());
00445   transition_joint_q.resize(m_robot->numJoints());
00446   qorg.resize(m_robot->numJoints());
00447   qrefv.resize(m_robot->numJoints());
00448   transition_count = 0;
00449   loop = 0;
00450   m_is_falling_counter = 0;
00451   is_air_counter = 0;
00452   total_mass = m_robot->totalMass();
00453   ref_zmp_aux = hrp::Vector3::Zero();
00454   m_actContactStates.data.length(m_contactStates.data.length());
00455   for (size_t i = 0; i < m_contactStates.data.length(); i++) {
00456     ref_contact_states.push_back(true);
00457     prev_ref_contact_states.push_back(true);
00458     m_actContactStates.data[i] = false;
00459     act_contact_states.push_back(false);
00460     toeheel_ratio.push_back(1.0);
00461   }
00462   m_COPInfo.data.length(m_contactStates.data.length()*3); // nx, ny, fz for each end-effectors
00463   for (size_t i = 0; i < m_COPInfo.data.length(); i++) {
00464       m_COPInfo.data[i] = 0.0;
00465   }
00466   transition_time = 2.0;
00467   foot_origin_offset[0] = hrp::Vector3::Zero();
00468   foot_origin_offset[1] = hrp::Vector3::Zero();
00469 
00470   //
00471   act_cogvel_filter = boost::shared_ptr<FirstOrderLowPassFilter<hrp::Vector3> >(new FirstOrderLowPassFilter<hrp::Vector3>(4.0, dt, hrp::Vector3::Zero())); // [Hz]
00472 
00473   // for debug output
00474   m_originRefZmp.data.x = m_originRefZmp.data.y = m_originRefZmp.data.z = 0.0;
00475   m_originRefCog.data.x = m_originRefCog.data.y = m_originRefCog.data.z = 0.0;
00476   m_originRefCogVel.data.x = m_originRefCogVel.data.y = m_originRefCogVel.data.z = 0.0;
00477   m_originNewZmp.data.x = m_originNewZmp.data.y = m_originNewZmp.data.z = 0.0;
00478   m_originActZmp.data.x = m_originActZmp.data.y = m_originActZmp.data.z = 0.0;
00479   m_originActCog.data.x = m_originActCog.data.y = m_originActCog.data.z = 0.0;
00480   m_originActCogVel.data.x = m_originActCogVel.data.y = m_originActCogVel.data.z = 0.0;
00481   m_allRefWrench.data.length(stikp.size() * 6); // 6 is wrench dim
00482   m_allEEComp.data.length(stikp.size() * 6); // 6 is pos+rot dim
00483   m_debugData.data.length(1); m_debugData.data[0] = 0.0;
00484 
00485   //
00486   szd = new SimpleZMPDistributor(dt);
00487   std::vector<std::vector<Eigen::Vector2d> > support_polygon_vec;
00488   for (size_t i = 0; i < stikp.size(); i++) {
00489       support_polygon_vec.push_back(std::vector<Eigen::Vector2d>(1,Eigen::Vector2d::Zero()));
00490   }
00491   szd->set_vertices(support_polygon_vec);
00492 
00493   rel_ee_pos.reserve(stikp.size());
00494   rel_ee_rot.reserve(stikp.size());
00495   rel_ee_name.reserve(stikp.size());
00496 
00497   hrp::Sensor* sen = m_robot->sensor<hrp::RateGyroSensor>("gyrometer");
00498   if (sen == NULL) {
00499       std::cerr << "[" << m_profile.instance_name << "] WARNING! This robot model has no GyroSensor named 'gyrometer'! " << std::endl;
00500   }
00501   return RTC::RTC_OK;
00502 }
00503 
00504 
00505 RTC::ReturnCode_t Stabilizer::onFinalize()
00506 {
00507   if (szd == NULL) {
00508       delete szd;
00509       szd = NULL;
00510   }
00511   return RTC::RTC_OK;
00512 }
00513 
00514 /*
00515 RTC::ReturnCode_t Stabilizer::onStartup(RTC::UniqueId ec_id)
00516 {
00517   return RTC::RTC_OK;
00518 }
00519 */
00520 
00521 /*
00522 RTC::ReturnCode_t Stabilizer::onShutdown(RTC::UniqueId ec_id)
00523 {
00524   return RTC::RTC_OK;
00525 }
00526 */
00527 
00528 RTC::ReturnCode_t Stabilizer::onActivated(RTC::UniqueId ec_id)
00529 {
00530   std::cerr << "[" << m_profile.instance_name<< "] onActivated(" << ec_id << ")" << std::endl;
00531   return RTC::RTC_OK;
00532 }
00533 
00534 RTC::ReturnCode_t Stabilizer::onDeactivated(RTC::UniqueId ec_id)
00535 {
00536   Guard guard(m_mutex);
00537   std::cerr << "[" << m_profile.instance_name<< "] onDeactivated(" << ec_id << ")" << std::endl;
00538   if ( (control_mode == MODE_ST || control_mode == MODE_AIR) ) {
00539     sync_2_idle ();
00540     control_mode = MODE_IDLE;
00541     transition_count = 1; // sync in one controller loop
00542   }
00543   return RTC::RTC_OK;
00544 }
00545 
00546 #define DEBUGP ((m_debugLevel==1 && loop%200==0) || m_debugLevel > 1 )
00547 #define DEBUGP2 (loop%10==0)
00548 RTC::ReturnCode_t Stabilizer::onExecute(RTC::UniqueId ec_id)
00549 {
00550   loop++;
00551   // std::cout << m_profile.instance_name<< ": onExecute(" << ec_id << ")" << std::endl;
00552 
00553   if (m_qRefIn.isNew()) {
00554     m_qRefIn.read();
00555   }
00556   if (m_qCurrentIn.isNew()) {
00557     m_qCurrentIn.read();
00558   }
00559   if (m_rpyIn.isNew()) {
00560     m_rpyIn.read();
00561   }
00562   if (m_zmpRefIn.isNew()) {
00563     m_zmpRefIn.read();
00564   }
00565   if (m_basePosIn.isNew()){
00566     m_basePosIn.read();
00567   }
00568   if (m_baseRpyIn.isNew()){
00569     m_baseRpyIn.read();
00570   }
00571   if (m_contactStatesIn.isNew()){
00572     m_contactStatesIn.read();
00573     for (size_t i = 0; i < m_contactStates.data.length(); i++) {
00574       ref_contact_states[i] = m_contactStates.data[i];
00575     }
00576   }
00577   if (m_toeheelRatioIn.isNew()){
00578     m_toeheelRatioIn.read();
00579     for (size_t i = 0; i < m_toeheelRatio.data.length(); i++) {
00580       toeheel_ratio[i] = m_toeheelRatio.data[i];
00581     }
00582   }
00583   if (m_controlSwingSupportTimeIn.isNew()){
00584     m_controlSwingSupportTimeIn.read();
00585   }
00586   for (size_t i = 0; i < m_wrenchesIn.size(); ++i) {
00587     if ( m_wrenchesIn[i]->isNew() ) {
00588       m_wrenchesIn[i]->read();
00589     }
00590   }
00591   for (size_t i = 0; i < m_ref_wrenchesIn.size(); ++i) {
00592     if ( m_ref_wrenchesIn[i]->isNew() ) {
00593       m_ref_wrenchesIn[i]->read();
00594     }
00595   }
00596   Guard guard(m_mutex);
00597   for (size_t i = 0; i < m_limbCOPOffsetIn.size(); ++i) {
00598     if ( m_limbCOPOffsetIn[i]->isNew() ) {
00599       m_limbCOPOffsetIn[i]->read();
00600       //stikp[i].localCOPPos = stikp[i].localp + stikp[i].localR * hrp::Vector3(m_limbCOPOffset[i].data.x, m_limbCOPOffset[i].data.y, m_limbCOPOffset[i].data.z);
00601       stikp[i].localCOPPos = stikp[i].localp + stikp[i].localR * hrp::Vector3(m_limbCOPOffset[i].data.x, 0, m_limbCOPOffset[i].data.z);
00602     }
00603   }
00604   if (m_qRefSeqIn.isNew()) {
00605     m_qRefSeqIn.read();
00606     is_seq_interpolating = true;
00607   } else {
00608     is_seq_interpolating = false;
00609   }
00610   if (m_walkingStatesIn.isNew()){
00611     m_walkingStatesIn.read();
00612     is_walking = m_walkingStates.data;
00613   }
00614   if (m_sbpCogOffsetIn.isNew()){
00615     m_sbpCogOffsetIn.read();
00616     sbp_cog_offset(0) = m_sbpCogOffset.data.x;
00617     sbp_cog_offset(1) = m_sbpCogOffset.data.y;
00618     sbp_cog_offset(2) = m_sbpCogOffset.data.z;
00619   }
00620 
00621   if (is_legged_robot) {
00622     getCurrentParameters();
00623     getTargetParameters();
00624     getActualParameters();
00625     calcStateForEmergencySignal();
00626     switch (control_mode) {
00627     case MODE_IDLE:
00628       break;
00629     case MODE_AIR:
00630       if ( transition_count == 0 && on_ground ) sync_2_st();
00631       break;
00632     case MODE_ST:
00633       if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00634         calcEEForceMomentControl();
00635       } else {
00636         calcTPCC();
00637       }
00638       if ( transition_count == 0 && !on_ground ) {
00639           if (is_air_counter < detection_count_to_air) ++is_air_counter;
00640           else control_mode = MODE_SYNC_TO_AIR;
00641       } else is_air_counter = 0;
00642       break;
00643     case MODE_SYNC_TO_IDLE:
00644       sync_2_idle();
00645       control_mode = MODE_IDLE;
00646       break;
00647     case MODE_SYNC_TO_AIR:
00648       sync_2_idle();
00649       control_mode = MODE_AIR;
00650       break;
00651     }
00652   }
00653   if ( m_robot->numJoints() == m_qRef.data.length() ) {
00654     if (is_legged_robot) {
00655       for ( int i = 0; i < m_robot->numJoints(); i++ ){
00656         m_qRef.data[i] = m_robot->joint(i)->q;
00657         //m_tau.data[i] = m_robot->joint(i)->u;
00658       }
00659       m_zmp.data.x = rel_act_zmp(0);
00660       m_zmp.data.y = rel_act_zmp(1);
00661       m_zmp.data.z = rel_act_zmp(2);
00662       m_zmp.tm = m_qRef.tm;
00663       m_zmpOut.write();
00664       m_refCP.data.x = rel_ref_cp(0);
00665       m_refCP.data.y = rel_ref_cp(1);
00666       m_refCP.data.z = rel_ref_cp(2);
00667       m_refCP.tm = m_qRef.tm;
00668       m_refCPOut.write();
00669       m_actCP.data.x = rel_act_cp(0);
00670       m_actCP.data.y = rel_act_cp(1);
00671       m_actCP.data.z = rel_act_cp(2);
00672       m_actCP.tm = m_qRef.tm;
00673       m_actCPOut.write();
00674       {
00675         hrp::Vector3 tmp_diff_cp = ref_foot_origin_rot * (ref_cp - act_cp - cp_offset);
00676         m_diffCP.data.x = tmp_diff_cp(0);
00677         m_diffCP.data.y = tmp_diff_cp(1);
00678         m_diffCP.data.z = tmp_diff_cp(2);
00679         m_diffCP.tm = m_qRef.tm;
00680         m_diffCPOut.write();
00681       }
00682       m_diffFootOriginExtMoment.data.x = diff_foot_origin_ext_moment(0);
00683       m_diffFootOriginExtMoment.data.y = diff_foot_origin_ext_moment(1);
00684       m_diffFootOriginExtMoment.data.z = diff_foot_origin_ext_moment(2);
00685       m_diffFootOriginExtMoment.tm = m_qRef.tm;
00686       m_diffFootOriginExtMomentOut.write();
00687       m_actContactStates.tm = m_qRef.tm;
00688       m_actContactStatesOut.write();
00689       m_COPInfo.tm = m_qRef.tm;
00690       m_COPInfoOut.write();
00691       //m_tauOut.write();
00692       // for debug output
00693       m_originRefZmp.data.x = ref_zmp(0); m_originRefZmp.data.y = ref_zmp(1); m_originRefZmp.data.z = ref_zmp(2);
00694       m_originRefCog.data.x = ref_cog(0); m_originRefCog.data.y = ref_cog(1); m_originRefCog.data.z = ref_cog(2);
00695       m_originRefCogVel.data.x = ref_cogvel(0); m_originRefCogVel.data.y = ref_cogvel(1); m_originRefCogVel.data.z = ref_cogvel(2);
00696       m_originNewZmp.data.x = new_refzmp(0); m_originNewZmp.data.y = new_refzmp(1); m_originNewZmp.data.z = new_refzmp(2);
00697       m_originActZmp.data.x = act_zmp(0); m_originActZmp.data.y = act_zmp(1); m_originActZmp.data.z = act_zmp(2);
00698       m_originActCog.data.x = act_cog(0); m_originActCog.data.y = act_cog(1); m_originActCog.data.z = act_cog(2);
00699       m_originActCogVel.data.x = act_cogvel(0); m_originActCogVel.data.y = act_cogvel(1); m_originActCogVel.data.z = act_cogvel(2);
00700       m_originRefZmp.tm = m_qRef.tm;
00701       m_originRefZmpOut.write();
00702       m_originRefCog.tm = m_qRef.tm;
00703       m_originRefCogOut.write();
00704       m_originRefCogVel.tm = m_qRef.tm;
00705       m_originRefCogVelOut.write();
00706       m_originNewZmp.tm = m_qRef.tm;
00707       m_originNewZmpOut.write();
00708       m_originActZmp.tm = m_qRef.tm;
00709       m_originActZmpOut.write();
00710       m_originActCog.tm = m_qRef.tm;
00711       m_originActCogOut.write();
00712       m_originActCogVel.tm = m_qRef.tm;
00713       m_originActCogVelOut.write();
00714       for (size_t i = 0; i < stikp.size(); i++) {
00715           for (size_t j = 0; j < 3; j++) {
00716               m_allRefWrench.data[6*i+j] = stikp[i].ref_force(j);
00717               m_allRefWrench.data[6*i+j+3] = stikp[i].ref_moment(j);
00718               m_allEEComp.data[6*i+j] = stikp[i].d_foot_pos(j);
00719               m_allEEComp.data[6*i+j+3] = stikp[i].d_foot_rpy(j);
00720           }
00721       }
00722       m_allRefWrench.tm = m_qRef.tm;
00723       m_allRefWrenchOut.write();
00724       m_allEEComp.tm = m_qRef.tm;
00725       m_allEECompOut.write();
00726       m_actBaseRpy.data.r = act_base_rpy(0);
00727       m_actBaseRpy.data.p = act_base_rpy(1);
00728       m_actBaseRpy.data.y = act_base_rpy(2);
00729       m_actBaseRpy.tm = m_qRef.tm;
00730       m_currentBaseRpy.data.r = current_base_rpy(0);
00731       m_currentBaseRpy.data.p = current_base_rpy(1);
00732       m_currentBaseRpy.data.y = current_base_rpy(2);
00733       m_currentBaseRpy.tm = m_qRef.tm;
00734       m_currentBasePos.data.x = current_base_pos(0);
00735       m_currentBasePos.data.y = current_base_pos(1);
00736       m_currentBasePos.data.z = current_base_pos(2);
00737       m_currentBasePos.tm = m_qRef.tm;
00738       m_actBaseRpyOut.write();
00739       m_currentBaseRpyOut.write();
00740       m_currentBasePosOut.write();
00741       m_debugData.tm = m_qRef.tm;
00742       m_debugDataOut.write();
00743     }
00744     m_qRefOut.write();
00745     // emergencySignal
00746     if (reset_emergency_flag) {
00747       m_emergencySignal.data = 0;
00748       m_emergencySignalOut.write();
00749       reset_emergency_flag = false;
00750     } else if (is_emergency) {
00751       m_emergencySignal.data = 1;
00752       m_emergencySignalOut.write();
00753     }
00754   }
00755 
00756   return RTC::RTC_OK;
00757 }
00758 
00759 void Stabilizer::getCurrentParameters ()
00760 {
00761   current_root_p = m_robot->rootLink()->p;
00762   current_root_R = m_robot->rootLink()->R;
00763   for ( int i = 0; i < m_robot->numJoints(); i++ ){
00764     qorg[i] = m_robot->joint(i)->q;
00765   }
00766 }
00767 
00768 void Stabilizer::calcFootOriginCoords (hrp::Vector3& foot_origin_pos, hrp::Matrix33& foot_origin_rot)
00769 {
00770   rats::coordinates leg_c[2], tmpc;
00771   hrp::Vector3 ez = hrp::Vector3::UnitZ();
00772   hrp::Vector3 ex = hrp::Vector3::UnitX();
00773   for (size_t i = 0; i < stikp.size(); i++) {
00774     if (stikp[i].ee_name.find("leg") == std::string::npos) continue;
00775     hrp::Link* target = m_robot->sensor<hrp::ForceSensor>(stikp[i].sensor_name)->link;
00776     leg_c[i].pos = target->p + target->R * foot_origin_offset[i];
00777     hrp::Vector3 xv1(target->R * ex);
00778     xv1(2)=0.0;
00779     xv1.normalize();
00780     hrp::Vector3 yv1(ez.cross(xv1));
00781     leg_c[i].rot(0,0) = xv1(0); leg_c[i].rot(1,0) = xv1(1); leg_c[i].rot(2,0) = xv1(2);
00782     leg_c[i].rot(0,1) = yv1(0); leg_c[i].rot(1,1) = yv1(1); leg_c[i].rot(2,1) = yv1(2);
00783     leg_c[i].rot(0,2) = ez(0); leg_c[i].rot(1,2) = ez(1); leg_c[i].rot(2,2) = ez(2);
00784   }
00785   if (ref_contact_states[contact_states_index_map["rleg"]] &&
00786       ref_contact_states[contact_states_index_map["lleg"]]) {
00787     rats::mid_coords(tmpc, 0.5, leg_c[0], leg_c[1]);
00788     foot_origin_pos = tmpc.pos;
00789     foot_origin_rot = tmpc.rot;
00790   } else if (ref_contact_states[contact_states_index_map["rleg"]]) {
00791     foot_origin_pos = leg_c[contact_states_index_map["rleg"]].pos;
00792     foot_origin_rot = leg_c[contact_states_index_map["rleg"]].rot;
00793   } else {
00794     foot_origin_pos = leg_c[contact_states_index_map["lleg"]].pos;
00795     foot_origin_rot = leg_c[contact_states_index_map["lleg"]].rot;
00796   }
00797 }
00798 
00799 void Stabilizer::getActualParameters ()
00800 {
00801   // Actual world frame =>
00802   hrp::Vector3 foot_origin_pos;
00803   hrp::Matrix33 foot_origin_rot;
00804   if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00805     // update by current joint angles
00806     for ( int i = 0; i < m_robot->numJoints(); i++ ){
00807       m_robot->joint(i)->q = m_qCurrent.data[i];
00808     }
00809     // tempolary
00810     m_robot->rootLink()->p = hrp::Vector3::Zero();
00811     m_robot->calcForwardKinematics();
00812     hrp::Sensor* sen = m_robot->sensor<hrp::RateGyroSensor>("gyrometer");
00813     hrp::Matrix33 senR = sen->link->R * sen->localR;
00814     hrp::Matrix33 act_Rs(hrp::rotFromRpy(m_rpy.data.r, m_rpy.data.p, m_rpy.data.y));
00815     //hrp::Matrix33 act_Rs(hrp::rotFromRpy(m_rpy.data.r*0.5, m_rpy.data.p*0.5, m_rpy.data.y*0.5));
00816     m_robot->rootLink()->R = act_Rs * (senR.transpose() * m_robot->rootLink()->R);
00817     m_robot->calcForwardKinematics();
00818     act_base_rpy = hrp::rpyFromRot(m_robot->rootLink()->R);
00819     calcFootOriginCoords (foot_origin_pos, foot_origin_rot);
00820   } else {
00821     for ( int i = 0; i < m_robot->numJoints(); i++ ) {
00822       m_robot->joint(i)->q = qorg[i];
00823     }
00824     m_robot->rootLink()->p = current_root_p;
00825     m_robot->rootLink()->R = current_root_R;
00826     m_robot->calcForwardKinematics();
00827   }
00828   // cog
00829   act_cog = m_robot->calcCM();
00830   // zmp
00831   on_ground = false;
00832   if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00833     on_ground = calcZMP(act_zmp, zmp_origin_off+foot_origin_pos(2));
00834   } else {
00835     on_ground = calcZMP(act_zmp, ref_zmp(2));
00836   }
00837   // set actual contact states
00838   for (size_t i = 0; i < stikp.size(); i++) {
00839       std::string limb_name = stikp[i].ee_name;
00840       size_t idx = contact_states_index_map[limb_name];
00841       act_contact_states[idx] = isContact(idx);
00842       m_actContactStates.data[idx] = act_contact_states[idx];
00843   }
00844   // <= Actual world frame
00845 
00846   // convert absolute (in st) -> root-link relative
00847   rel_act_zmp = m_robot->rootLink()->R.transpose() * (act_zmp - m_robot->rootLink()->p);
00848   if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00849     // Actual foot_origin frame =>
00850     act_zmp = foot_origin_rot.transpose() * (act_zmp - foot_origin_pos);
00851     act_cog = foot_origin_rot.transpose() * (act_cog - foot_origin_pos);
00852     //act_cogvel = foot_origin_rot.transpose() * act_cogvel;
00853     if (ref_contact_states != prev_ref_contact_states) {
00854       act_cogvel = (foot_origin_rot.transpose() * prev_act_foot_origin_rot) * act_cogvel;
00855     } else {
00856       act_cogvel = (act_cog - prev_act_cog)/dt;
00857     }
00858     prev_act_foot_origin_rot = foot_origin_rot;
00859     act_cogvel = act_cogvel_filter->passFilter(act_cogvel);
00860     prev_act_cog = act_cog;
00861     //act_root_rot = m_robot->rootLink()->R;
00862     for (size_t i = 0; i < stikp.size(); i++) {
00863       hrp::Link* target = m_robot->link(stikp[i].target_name);
00864       //hrp::Vector3 act_ee_p = target->p + target->R * stikp[i].localCOPPos;
00865       hrp::Vector3 _act_ee_p = target->p + target->R * stikp[i].localp;
00866       act_ee_p[i] = foot_origin_rot.transpose() * (_act_ee_p - foot_origin_pos);
00867       act_ee_R[i] = foot_origin_rot.transpose() * (target->R * stikp[i].localR);
00868     }
00869     // capture point
00870     act_cp = act_cog + act_cogvel / std::sqrt(eefm_gravitational_acceleration / (act_cog - act_zmp)(2));
00871     rel_act_cp = hrp::Vector3(act_cp(0), act_cp(1), act_zmp(2));
00872     rel_act_cp = m_robot->rootLink()->R.transpose() * ((foot_origin_pos + foot_origin_rot * rel_act_cp) - m_robot->rootLink()->p);
00873     // <= Actual foot_origin frame
00874 
00875     // Actual world frame =>
00876     // new ZMP calculation
00877     // Kajita's feedback law
00878     //   Basically Equation (26) in the paper [1].
00879     hrp::Vector3 dcog=foot_origin_rot * (ref_cog - act_cog);
00880     hrp::Vector3 dcogvel=foot_origin_rot * (ref_cogvel - act_cogvel);
00881     hrp::Vector3 dzmp=foot_origin_rot * (ref_zmp - act_zmp);
00882     new_refzmp = foot_origin_rot * new_refzmp + foot_origin_pos;
00883     for (size_t i = 0; i < 2; i++) {
00884       new_refzmp(i) += eefm_k1[i] * transition_smooth_gain * dcog(i) + eefm_k2[i] * transition_smooth_gain * dcogvel(i) + eefm_k3[i] * transition_smooth_gain * dzmp(i) + ref_zmp_aux(i);
00885     }
00886     if (DEBUGP) {
00887       // All state variables are foot_origin coords relative
00888       std::cerr << "[" << m_profile.instance_name << "] state values" << std::endl;
00889       std::cerr << "[" << m_profile.instance_name << "]   "
00890                 << "ref_cog    = " << hrp::Vector3(ref_cog*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]"))
00891                 << ", act_cog    = " << hrp::Vector3(act_cog*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]")) << "[mm]" << std::endl;
00892       std::cerr << "[" << m_profile.instance_name << "]   "
00893                 << "ref_cogvel = " << hrp::Vector3(ref_cogvel*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]"))
00894                 << ", act_cogvel = " << hrp::Vector3(act_cogvel*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]")) << "[mm/s]" << std::endl;
00895       std::cerr << "[" << m_profile.instance_name << "]   "
00896                 << "ref_zmp    = " << hrp::Vector3(ref_zmp*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]"))
00897                 << ", act_zmp    = " << hrp::Vector3(act_zmp*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]")) << "[mm]" << std::endl;
00898       hrp::Vector3 tmpnew_refzmp;
00899       tmpnew_refzmp = foot_origin_rot.transpose()*(new_refzmp-foot_origin_pos); // Actual world -> foot origin relative
00900       std::cerr << "[" << m_profile.instance_name << "]   "
00901                 << "new_zmp    = " << hrp::Vector3(tmpnew_refzmp*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]"))
00902                 << ", dif_zmp    = " << hrp::Vector3((tmpnew_refzmp-ref_zmp)*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]")) << "[mm]" << std::endl;
00903     }
00904 
00905     std::vector<std::string> ee_name;
00906     // distribute new ZMP into foot force & moment
00907     std::vector<hrp::Vector3> tmp_ref_force, tmp_ref_moment;
00908     std::vector<double> limb_gains;
00909     std::vector<hrp::dvector6> ee_forcemoment_distribution_weight;
00910     std::vector<double> tmp_toeheel_ratio;
00911     if (control_mode == MODE_ST) {
00912       std::vector<hrp::Vector3> ee_pos, cop_pos;
00913       std::vector<hrp::Matrix33> ee_rot;
00914       std::vector<bool> is_contact_list;
00915       is_contact_list.reserve(stikp.size());
00916       for (size_t i = 0; i < stikp.size(); i++) {
00917           STIKParam& ikp = stikp[i];
00918           if (!is_feedback_control_enable[i]) continue;
00919           hrp::Link* target = m_robot->link(ikp.target_name);
00920           ee_pos.push_back(target->p + target->R * ikp.localp);
00921           cop_pos.push_back(target->p + target->R * ikp.localCOPPos);
00922           ee_rot.push_back(target->R * ikp.localR);
00923           ee_name.push_back(ikp.ee_name);
00924           limb_gains.push_back(ikp.swing_support_gain);
00925           tmp_ref_force.push_back(hrp::Vector3(foot_origin_rot * ref_force[i]));
00926           tmp_ref_moment.push_back(hrp::Vector3(foot_origin_rot * ref_moment[i]));
00927           rel_ee_pos.push_back(foot_origin_rot.transpose() * (ee_pos.back() - foot_origin_pos));
00928           rel_ee_rot.push_back(foot_origin_rot.transpose() * ee_rot.back());
00929           rel_ee_name.push_back(ee_name.back());
00930           is_contact_list.push_back(act_contact_states[i]);
00931           // std::cerr << ee_forcemoment_distribution_weight[i] << std::endl;
00932           ee_forcemoment_distribution_weight.push_back(hrp::dvector6::Zero(6,1));
00933           for (size_t j = 0; j < 6; j++) {
00934               ee_forcemoment_distribution_weight[i][j] = ikp.eefm_ee_forcemoment_distribution_weight[j];
00935           }
00936           tmp_toeheel_ratio.push_back(toeheel_ratio[i]);
00937       }
00938 
00939       // All state variables are foot_origin coords relative
00940       if (DEBUGP) {
00941           std::cerr << "[" << m_profile.instance_name << "] ee values" << std::endl;
00942           hrp::Vector3 tmpp;
00943           for (size_t i = 0; i < ee_name.size(); i++) {
00944               tmpp = foot_origin_rot.transpose()*(ee_pos[i]-foot_origin_pos);
00945               std::cerr << "[" << m_profile.instance_name << "]   "
00946                         << "ee_pos (" << ee_name[i] << ")    = " << hrp::Vector3(tmpp*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]"));
00947               tmpp = foot_origin_rot.transpose()*(cop_pos[i]-foot_origin_pos);
00948               std::cerr << ", cop_pos (" << ee_name[i] << ")    = " << hrp::Vector3(tmpp*1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "[", "]")) << "[mm]" << std::endl;
00949           }
00950       }
00951 
00952       // truncate ZMP
00953       if (use_zmp_truncation) {
00954         Eigen::Vector2d tmp_new_refzmp(new_refzmp.head(2));
00955         szd->get_vertices(support_polygon_vetices);
00956         szd->calc_convex_hull(support_polygon_vetices, ref_contact_states, ee_pos, ee_rot);
00957         if (!szd->is_inside_support_polygon(tmp_new_refzmp, hrp::Vector3::Zero(), true, std::string(m_profile.instance_name))) new_refzmp.head(2) = tmp_new_refzmp;
00958       }
00959 
00960       // Distribute ZMP into each EE force/moment at each COP
00961       if (st_algorithm == OpenHRP::StabilizerService::EEFM) {
00962           // Modified version of distribution in Equation (4)-(6) and (10)-(13) in the paper [1].
00963           szd->distributeZMPToForceMoments(tmp_ref_force, tmp_ref_moment,
00964                                            ee_pos, cop_pos, ee_rot, ee_name, limb_gains, tmp_toeheel_ratio,
00965                                            new_refzmp, hrp::Vector3(foot_origin_rot * ref_zmp + foot_origin_pos),
00966                                            eefm_gravitational_acceleration * total_mass, dt,
00967                                            DEBUGP, std::string(m_profile.instance_name));
00968       } else if (st_algorithm == OpenHRP::StabilizerService::EEFMQP) {
00969           szd->distributeZMPToForceMomentsQP(tmp_ref_force, tmp_ref_moment,
00970                                              ee_pos, cop_pos, ee_rot, ee_name, limb_gains, tmp_toeheel_ratio,
00971                                              new_refzmp, hrp::Vector3(foot_origin_rot * ref_zmp + foot_origin_pos),
00972                                              eefm_gravitational_acceleration * total_mass, dt,
00973                                              DEBUGP, std::string(m_profile.instance_name),
00974                                              (st_algorithm == OpenHRP::StabilizerService::EEFMQPCOP));
00975       } else if (st_algorithm == OpenHRP::StabilizerService::EEFMQPCOP) {
00976           szd->distributeZMPToForceMomentsPseudoInverse(tmp_ref_force, tmp_ref_moment,
00977                                              ee_pos, cop_pos, ee_rot, ee_name, limb_gains, tmp_toeheel_ratio,
00978                                              new_refzmp, hrp::Vector3(foot_origin_rot * ref_zmp + foot_origin_pos),
00979                                              eefm_gravitational_acceleration * total_mass, dt,
00980                                              DEBUGP, std::string(m_profile.instance_name),
00981                                              (st_algorithm == OpenHRP::StabilizerService::EEFMQPCOP), is_contact_list);
00982       } else if (st_algorithm == OpenHRP::StabilizerService::EEFMQPCOP2) {
00983           szd->distributeZMPToForceMomentsPseudoInverse2(tmp_ref_force, tmp_ref_moment,
00984                                                          ee_pos, cop_pos, ee_rot, ee_name, limb_gains, tmp_toeheel_ratio,
00985                                                          new_refzmp, hrp::Vector3(foot_origin_rot * ref_zmp + foot_origin_pos),
00986                                                          foot_origin_rot * ref_total_force, foot_origin_rot * ref_total_moment,
00987                                                          ee_forcemoment_distribution_weight,
00988                                                          eefm_gravitational_acceleration * total_mass, dt,
00989                                                          DEBUGP, std::string(m_profile.instance_name));
00990       }
00991       // for debug output
00992       new_refzmp = foot_origin_rot.transpose() * (new_refzmp - foot_origin_pos);
00993     }
00994 
00995     // foor modif
00996     if (control_mode == MODE_ST) {
00997       hrp::Vector3 f_diff(hrp::Vector3::Zero());
00998       std::vector<bool> large_swing_f_diff(3, false);
00999       // moment control
01000       act_total_foot_origin_moment = hrp::Vector3::Zero();
01001       for (size_t i = 0; i < stikp.size(); i++) {
01002         STIKParam& ikp = stikp[i];
01003         std::vector<bool> large_swing_m_diff(3, false);
01004         if (!is_feedback_control_enable[i]) continue;
01005         hrp::Sensor* sensor = m_robot->sensor<hrp::ForceSensor>(ikp.sensor_name);
01006         hrp::Link* target = m_robot->link(ikp.target_name);
01007         // Convert moment at COP => moment at ee
01008         size_t idx = contact_states_index_map[ikp.ee_name];
01009         ikp.ref_moment = tmp_ref_moment[idx] + ((target->R * ikp.localCOPPos + target->p) - (target->R * ikp.localp + target->p)).cross(tmp_ref_force[idx]);
01010         ikp.ref_force = tmp_ref_force[idx];
01011         // Actual world frame =>
01012         hrp::Vector3 sensor_force = (sensor->link->R * sensor->localR) * hrp::Vector3(m_wrenches[i].data[0], m_wrenches[i].data[1], m_wrenches[i].data[2]);
01013         hrp::Vector3 sensor_moment = (sensor->link->R * sensor->localR) * hrp::Vector3(m_wrenches[i].data[3], m_wrenches[i].data[4], m_wrenches[i].data[5]);
01014         //hrp::Vector3 ee_moment = ((sensor->link->R * sensor->localPos + sensor->link->p) - (target->R * ikp.localCOPPos + target->p)).cross(sensor_force) + sensor_moment;
01015         hrp::Vector3 ee_moment = ((sensor->link->R * sensor->localPos + sensor->link->p) - (target->R * ikp.localp + target->p)).cross(sensor_force) + sensor_moment;
01016         // <= Actual world frame
01017         // Convert force & moment as foot origin coords relative
01018         ikp.ref_moment = foot_origin_rot.transpose() * ikp.ref_moment;
01019         ikp.ref_force = foot_origin_rot.transpose() * ikp.ref_force;
01020         sensor_force = foot_origin_rot.transpose() * sensor_force;
01021         ee_moment = foot_origin_rot.transpose() * ee_moment;
01022         if ( i == 0 ) f_diff += -1*sensor_force;
01023         else f_diff += sensor_force;
01024         for (size_t j = 0; j < 3; ++j) {
01025             if ((!ref_contact_states[i] || !act_contact_states[i]) && fabs(ikp.ref_force(j) - sensor_force(j)) > eefm_swing_damping_force_thre[j]) large_swing_f_diff[j] = true;
01026             if ((!ref_contact_states[i] || !act_contact_states[i]) && (fabs(ikp.ref_moment(j) - ee_moment(j)) > eefm_swing_damping_moment_thre[j])) large_swing_m_diff[j] = true;
01027         }
01028         // Moment limitation
01029         hrp::Matrix33 ee_R(target->R * ikp.localR);
01030         ikp.ref_moment = ee_R * vlimit((ee_R.transpose() * ikp.ref_moment), ikp.eefm_ee_moment_limit);
01031         // calcDampingControl
01032         // d_foot_rpy and d_foot_pos is (actual) foot origin coords relative value because these use foot origin coords relative force & moment
01033         { // Rot
01034           //   Basically Equation (16) and (17) in the paper [1]
01035           hrp::Vector3 tmp_damping_gain;
01036           for (size_t j = 0; j < 3; ++j) {
01037               if (!eefm_use_swing_damping || !large_swing_m_diff[j]) tmp_damping_gain(j) = (1-transition_smooth_gain) * ikp.eefm_rot_damping_gain(j) * 10 + transition_smooth_gain * ikp.eefm_rot_damping_gain(j);
01038               else tmp_damping_gain(j) = (1-transition_smooth_gain) * eefm_swing_rot_damping_gain(j) * 10 + transition_smooth_gain * eefm_swing_rot_damping_gain(j);
01039           }
01040           ikp.d_foot_rpy = calcDampingControl(ikp.ref_moment, ee_moment, ikp.d_foot_rpy, tmp_damping_gain, ikp.eefm_rot_time_const);
01041           ikp.d_foot_rpy = vlimit(ikp.d_foot_rpy, -1 * ikp.eefm_rot_compensation_limit, ikp.eefm_rot_compensation_limit);
01042         }
01043         if (!eefm_use_force_difference_control) { // Pos
01044             hrp::Vector3 tmp_damping_gain = (1-transition_smooth_gain) * ikp.eefm_pos_damping_gain * 10 + transition_smooth_gain * ikp.eefm_pos_damping_gain;
01045             ikp.d_foot_pos = calcDampingControl(ikp.ref_force, sensor_force, ikp.d_foot_pos, tmp_damping_gain, ikp.eefm_pos_time_const_support);
01046             ikp.d_foot_pos = vlimit(ikp.d_foot_pos, -1 * ikp.eefm_pos_compensation_limit, ikp.eefm_pos_compensation_limit);
01047         }
01048         // Actual ee frame =>
01049         ikp.ee_d_foot_rpy = ee_R.transpose() * (foot_origin_rot * ikp.d_foot_rpy);
01050         // tilt Check : only flat plane is supported
01051         {
01052             hrp::Vector3 plane_x = target_ee_R[i].col(0);
01053             hrp::Vector3 plane_y = target_ee_R[i].col(1);
01054             hrp::Matrix33 act_ee_R_world = target->R * stikp[i].localR;
01055             hrp::Vector3 normal_vector = act_ee_R_world.col(2);
01056             /* projected_normal = c1 * plane_x + c2 * plane_y : c1 = plane_x.dot(normal_vector), c2 = plane_y.dot(normal_vector) because (normal-vector - projected_normal) is orthogonal to plane */
01057             projected_normal.at(i) = plane_x.dot(normal_vector) * plane_x + plane_y.dot(normal_vector) * plane_y;
01058             act_force.at(i) = sensor_force;
01059         }
01060         //act_total_foot_origin_moment += (target->R * ikp.localCOPPos + target->p).cross(sensor_force) + ee_moment;
01061         act_total_foot_origin_moment += (target->R * ikp.localp + target->p - foot_origin_pos).cross(sensor_force) + ee_moment;
01062       }
01063       act_total_foot_origin_moment = foot_origin_rot.transpose() * act_total_foot_origin_moment;
01064 
01065       if (eefm_use_force_difference_control) {
01066           // fxyz control
01067           // foot force difference control version
01068           //   Basically Equation (18) in the paper [1]
01069           hrp::Vector3 ref_f_diff = (stikp[1].ref_force-stikp[0].ref_force);
01070           if (eefm_use_swing_damping) {
01071             hrp::Vector3 tmp_damping_gain;
01072             for (size_t i = 0; i < 3; ++i) {
01073                 if (!large_swing_f_diff[i]) tmp_damping_gain(i) = (1-transition_smooth_gain) * stikp[0].eefm_pos_damping_gain(i) * 10 + transition_smooth_gain * stikp[0].eefm_pos_damping_gain(i);
01074                 else tmp_damping_gain(i) = (1-transition_smooth_gain) * eefm_swing_pos_damping_gain(i) * 10 + transition_smooth_gain * eefm_swing_pos_damping_gain(i);
01075             }
01076             pos_ctrl = calcDampingControl (ref_f_diff, f_diff, pos_ctrl,
01077                                            tmp_damping_gain, stikp[0].eefm_pos_time_const_support);
01078           } else {
01079             if ( (ref_contact_states[contact_states_index_map["rleg"]] && ref_contact_states[contact_states_index_map["lleg"]]) // Reference : double support phase
01080                  || (act_contact_states[0] && act_contact_states[1]) ) { // Actual : double support phase
01081               // Temporarily use first pos damping gain (stikp[0])
01082               hrp::Vector3 tmp_damping_gain = (1-transition_smooth_gain) * stikp[0].eefm_pos_damping_gain * 10 + transition_smooth_gain * stikp[0].eefm_pos_damping_gain;
01083               pos_ctrl = calcDampingControl (ref_f_diff, f_diff, pos_ctrl,
01084                                              tmp_damping_gain, stikp[0].eefm_pos_time_const_support);
01085             } else {
01086               double remain_swing_time;
01087               if ( !ref_contact_states[contact_states_index_map["rleg"]] ) { // rleg swing
01088                   remain_swing_time = m_controlSwingSupportTime.data[contact_states_index_map["rleg"]];
01089               } else { // lleg swing
01090                   remain_swing_time = m_controlSwingSupportTime.data[contact_states_index_map["lleg"]];
01091               }
01092               // std::cerr << "st " << remain_swing_time << " rleg " << contact_states[contact_states_index_map["rleg"]] << " lleg " << contact_states[contact_states_index_map["lleg"]] << std::endl;
01093               double tmp_ratio = std::max(0.0, std::min(1.0, 1.0 - (remain_swing_time-eefm_pos_margin_time)/eefm_pos_transition_time)); // 0=>1
01094               // Temporarily use first pos damping gain (stikp[0])
01095               hrp::Vector3 tmp_damping_gain = (1-transition_smooth_gain) * stikp[0].eefm_pos_damping_gain * 10 + transition_smooth_gain * stikp[0].eefm_pos_damping_gain;
01096               hrp::Vector3 tmp_time_const = (1-tmp_ratio)*eefm_pos_time_const_swing*hrp::Vector3::Ones()+tmp_ratio*stikp[0].eefm_pos_time_const_support;
01097               pos_ctrl = calcDampingControl (tmp_ratio * ref_f_diff, tmp_ratio * f_diff, pos_ctrl, tmp_damping_gain, tmp_time_const);
01098             }
01099           }
01100           // zctrl = vlimit(zctrl, -0.02, 0.02);
01101           // Temporarily use first pos compensation limit (stikp[0])
01102           pos_ctrl = vlimit(pos_ctrl, -1 * stikp[0].eefm_pos_compensation_limit * 2, stikp[0].eefm_pos_compensation_limit * 2);
01103           // Divide pos_ctrl into rfoot and lfoot
01104           stikp[0].d_foot_pos = -0.5 * pos_ctrl;
01105           stikp[1].d_foot_pos = 0.5 * pos_ctrl;
01106       }
01107       if (DEBUGP) {
01108         std::cerr << "[" << m_profile.instance_name << "] Control values" << std::endl;
01109         if (eefm_use_force_difference_control) {
01110             std::cerr << "[" << m_profile.instance_name << "]   "
01111                       << "pos_ctrl    = [" << pos_ctrl(0)*1e3 << " " << pos_ctrl(1)*1e3 << " "<< pos_ctrl(2)*1e3 << "] [mm]" << std::endl;
01112         }
01113         for (size_t i = 0; i < ee_name.size(); i++) {
01114             std::cerr << "[" << m_profile.instance_name << "]   "
01115                       << "d_foot_pos (" << ee_name[i] << ")  = [" << stikp[i].d_foot_pos(0)*1e3 << " " << stikp[i].d_foot_pos(1)*1e3 << " " << stikp[i].d_foot_pos(2)*1e3 << "] [mm], "
01116                       << "d_foot_rpy (" << ee_name[i] << ")  = [" << stikp[i].d_foot_rpy(0)*180.0/M_PI << " " << stikp[i].d_foot_rpy(1)*180.0/M_PI << " " << stikp[i].d_foot_rpy(2)*180.0/M_PI << "] [deg]" << std::endl;
01117         }
01118       }
01119       // foot force independent damping control
01120       // for (size_t i = 0; i < 2; i++) {
01121       //   f_zctrl[i] = calcDampingControl (ref_force[i](2),
01122       //                                    fz[i], f_zctrl[i], eefm_pos_damping_gain, eefm_pos_time_const);
01123       //   f_zctrl[i] = vlimit(f_zctrl[i], -0.05, 0.05);
01124       // }
01125       calcDiffFootOriginExtMoment ();
01126     }
01127   } // st_algorithm == OpenHRP::StabilizerService::EEFM
01128 
01129   for ( int i = 0; i < m_robot->numJoints(); i++ ){
01130     m_robot->joint(i)->q = qrefv[i];
01131   }
01132   m_robot->rootLink()->p = target_root_p;
01133   m_robot->rootLink()->R = target_root_R;
01134   if ( !(control_mode == MODE_IDLE || control_mode == MODE_AIR) ) {
01135     for (size_t i = 0; i < jpe_v.size(); i++) {
01136       if (is_ik_enable[i]) {
01137         for ( int j = 0; j < jpe_v[i]->numJoints(); j++ ){
01138           int idx = jpe_v[i]->joint(j)->jointId;
01139           m_robot->joint(idx)->q = qorg[idx];
01140         }
01141       }
01142     }
01143     m_robot->rootLink()->p(0) = current_root_p(0);
01144     m_robot->rootLink()->p(1) = current_root_p(1);
01145     m_robot->rootLink()->R = current_root_R;
01146     m_robot->calcForwardKinematics();
01147   }
01148   copy (ref_contact_states.begin(), ref_contact_states.end(), prev_ref_contact_states.begin());
01149   if (control_mode != MODE_ST) d_pos_z_root = 0.0;
01150 }
01151 
01152 void Stabilizer::getTargetParameters ()
01153 {
01154   // Reference world frame =>
01155   // update internal robot model
01156   if ( transition_count == 0 ) {
01157     transition_smooth_gain = 1.0;
01158   } else {
01159     double max_transition_count = calcMaxTransitionCount();
01160     transition_smooth_gain = 1/(1+exp(-9.19*(((max_transition_count - std::fabs(transition_count)) / max_transition_count) - 0.5)));
01161   }
01162   if (transition_count > 0) {
01163     for ( int i = 0; i < m_robot->numJoints(); i++ ){
01164       m_robot->joint(i)->q = ( m_qRef.data[i] - transition_joint_q[i] ) * transition_smooth_gain + transition_joint_q[i];
01165     }
01166   } else {
01167     for ( int i = 0; i < m_robot->numJoints(); i++ ){
01168       m_robot->joint(i)->q = m_qRef.data[i];
01169     }
01170   }
01171   if ( transition_count < 0 ) {
01172     transition_count++;
01173   } else if ( transition_count > 0 ) {
01174     if ( transition_count == 1 ) {
01175       std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm << "] Move to MODE_IDLE" << std::endl;
01176       reset_emergency_flag = true;
01177     }
01178     transition_count--;
01179   }
01180   for ( int i = 0; i < m_robot->numJoints(); i++ ){
01181     qrefv[i] = m_robot->joint(i)->q;
01182   }
01183   m_robot->rootLink()->p = hrp::Vector3(m_basePos.data.x, m_basePos.data.y, m_basePos.data.z);
01184   target_root_p = m_robot->rootLink()->p;
01185   target_root_R = hrp::rotFromRpy(m_baseRpy.data.r, m_baseRpy.data.p, m_baseRpy.data.y);
01186   m_robot->rootLink()->R = target_root_R;
01187   m_robot->calcForwardKinematics();
01188   ref_zmp = m_robot->rootLink()->R * hrp::Vector3(m_zmpRef.data.x, m_zmpRef.data.y, m_zmpRef.data.z) + m_robot->rootLink()->p; // base frame -> world frame
01189   hrp::Vector3 foot_origin_pos;
01190   hrp::Matrix33 foot_origin_rot;
01191   calcFootOriginCoords (foot_origin_pos, foot_origin_rot);
01192   if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
01193     // apply inverse system
01194     hrp::Vector3 tmp_ref_zmp = ref_zmp + eefm_zmp_delay_time_const[0] * (ref_zmp - prev_ref_zmp) / dt;
01195     prev_ref_zmp = ref_zmp;
01196     ref_zmp = tmp_ref_zmp;
01197   }
01198   ref_cog = m_robot->calcCM();
01199   ref_total_force = hrp::Vector3::Zero();
01200   ref_total_moment = hrp::Vector3::Zero(); // Total moment around reference ZMP tmp
01201   ref_total_foot_origin_moment = hrp::Vector3::Zero();
01202   for (size_t i = 0; i < stikp.size(); i++) {
01203     hrp::Link* target = m_robot->link(stikp[i].target_name);
01204     //target_ee_p[i] = target->p + target->R * stikp[i].localCOPPos;
01205     target_ee_p[i] = target->p + target->R * stikp[i].localp;
01206     target_ee_R[i] = target->R * stikp[i].localR;
01207     ref_force[i] = hrp::Vector3(m_ref_wrenches[i].data[0], m_ref_wrenches[i].data[1], m_ref_wrenches[i].data[2]);
01208     ref_moment[i] = hrp::Vector3(m_ref_wrenches[i].data[3], m_ref_wrenches[i].data[4], m_ref_wrenches[i].data[5]);
01209     ref_total_force += ref_force[i];
01210     // Force/moment diff control
01211     ref_total_moment += (target_ee_p[i]-ref_zmp).cross(ref_force[i]);
01212     // Force/moment control
01213     // ref_total_moment += (target_ee_p[i]-ref_zmp).cross(hrp::Vector3(m_ref_wrenches[i].data[0], m_ref_wrenches[i].data[1], m_ref_wrenches[i].data[2]))
01214     //     + hrp::Vector3(m_ref_wrenches[i].data[3], m_ref_wrenches[i].data[4], m_ref_wrenches[i].data[5]);
01215     if (is_feedback_control_enable[i]) {
01216         ref_total_foot_origin_moment += (target_ee_p[i]-foot_origin_pos).cross(ref_force[i]) + ref_moment[i];
01217     }
01218   }
01219   // <= Reference world frame
01220 
01221   // Reset prev_ref_cog for transition (MODE_IDLE=>MODE_ST) because the coordinates for ref_cog differs among st algorithms.
01222   if (transition_count == (-1 * calcMaxTransitionCount() + 1)) { // max transition count. In MODE_IDLE => MODE_ST, transition_count is < 0 and upcounter. "+ 1" is upcount at the beginning of this function.
01223       prev_ref_cog = ref_cog;
01224       std::cerr << "[" << m_profile.instance_name << "]   Reset prev_ref_cog for transition (MODE_IDLE=>MODE_ST)." << std::endl;
01225   }
01226 
01227   if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
01228     // Reference foot_origin frame =>
01229     // initialize for new_refzmp
01230     new_refzmp = ref_zmp;
01231     rel_cog = m_robot->rootLink()->R.transpose() * (ref_cog-m_robot->rootLink()->p);
01232     // convert world (current-tmp) => local (foot_origin)
01233     zmp_origin_off = ref_zmp(2) - foot_origin_pos(2);
01234     ref_zmp = foot_origin_rot.transpose() * (ref_zmp - foot_origin_pos);
01235     ref_cog = foot_origin_rot.transpose() * (ref_cog - foot_origin_pos);
01236     new_refzmp = foot_origin_rot.transpose() * (new_refzmp - foot_origin_pos);
01237     if (ref_contact_states != prev_ref_contact_states) {
01238       ref_cogvel = (foot_origin_rot.transpose() * prev_ref_foot_origin_rot) * ref_cogvel;
01239     } else {
01240       ref_cogvel = (ref_cog - prev_ref_cog)/dt;
01241     }
01242     prev_ref_foot_origin_rot = ref_foot_origin_rot = foot_origin_rot;
01243     for (size_t i = 0; i < stikp.size(); i++) {
01244       stikp[i].target_ee_diff_p = foot_origin_rot.transpose() * (target_ee_p[i] - foot_origin_pos);
01245       stikp[i].target_ee_diff_r = foot_origin_rot.transpose() * target_ee_R[i];
01246       ref_force[i] = foot_origin_rot.transpose() * ref_force[i];
01247       ref_moment[i] = foot_origin_rot.transpose() * ref_moment[i];
01248     }
01249     ref_total_foot_origin_moment = foot_origin_rot.transpose() * ref_total_foot_origin_moment;
01250     ref_total_force = foot_origin_rot.transpose() * ref_total_force;
01251     ref_total_moment = foot_origin_rot.transpose() * ref_total_moment;
01252     target_foot_origin_rot = foot_origin_rot;
01253     // capture point
01254     ref_cp = ref_cog + ref_cogvel / std::sqrt(eefm_gravitational_acceleration / (ref_cog - ref_zmp)(2));
01255     rel_ref_cp = hrp::Vector3(ref_cp(0), ref_cp(1), ref_zmp(2));
01256     rel_ref_cp = m_robot->rootLink()->R.transpose() * ((foot_origin_pos + foot_origin_rot * rel_ref_cp) - m_robot->rootLink()->p);
01257     sbp_cog_offset = foot_origin_rot.transpose() * sbp_cog_offset;
01258     // <= Reference foot_origin frame
01259   } else {
01260     ref_cogvel = (ref_cog - prev_ref_cog)/dt;
01261   } // st_algorithm == OpenHRP::StabilizerService::EEFM
01262   prev_ref_cog = ref_cog;
01263   // Calc swing support limb gain param
01264   calcSwingSupportLimbGain();
01265 }
01266 
01267 bool Stabilizer::calcZMP(hrp::Vector3& ret_zmp, const double zmp_z)
01268 {
01269   double tmpzmpx = 0;
01270   double tmpzmpy = 0;
01271   double tmpfz = 0, tmpfz2 = 0.0;
01272   for (size_t i = 0; i < stikp.size(); i++) {
01273     if (!is_zmp_calc_enable[i]) continue;
01274     hrp::ForceSensor* sensor = m_robot->sensor<hrp::ForceSensor>(stikp[i].sensor_name);
01275     hrp::Vector3 fsp = sensor->link->p + sensor->link->R * sensor->localPos;
01276     hrp::Matrix33 tmpR;
01277     rats::rotm3times(tmpR, sensor->link->R, sensor->localR);
01278     hrp::Vector3 nf = tmpR * hrp::Vector3(m_wrenches[i].data[0], m_wrenches[i].data[1], m_wrenches[i].data[2]);
01279     hrp::Vector3 nm = tmpR * hrp::Vector3(m_wrenches[i].data[3], m_wrenches[i].data[4], m_wrenches[i].data[5]);
01280     tmpzmpx += nf(2) * fsp(0) - (fsp(2) - zmp_z) * nf(0) - nm(1);
01281     tmpzmpy += nf(2) * fsp(1) - (fsp(2) - zmp_z) * nf(1) + nm(0);
01282     tmpfz += nf(2);
01283     // calc ee-local COP
01284     hrp::Link* target = m_robot->link(stikp[i].target_name);
01285     hrp::Matrix33 eeR = target->R * stikp[i].localR;
01286     hrp::Vector3 ee_fsp = eeR.transpose() * (fsp - (target->p + target->R * stikp[i].localp)); // ee-local force sensor pos
01287     nf = eeR.transpose() * nf;
01288     nm = eeR.transpose() * nm;
01289     // ee-local total moment and total force at ee position
01290     double tmpcopmy = nf(2) * ee_fsp(0) - nf(0) * ee_fsp(2) - nm(1);
01291     double tmpcopmx = nf(2) * ee_fsp(1) - nf(1) * ee_fsp(2) + nm(0);
01292     double tmpcopfz = nf(2);
01293     m_COPInfo.data[i*3] = tmpcopmx;
01294     m_COPInfo.data[i*3+1] = tmpcopmy;
01295     m_COPInfo.data[i*3+2] = tmpcopfz;
01296     prev_act_force_z[i] = 0.85 * prev_act_force_z[i] + 0.15 * nf(2); // filter, cut off 5[Hz]
01297     tmpfz2 += prev_act_force_z[i];
01298   }
01299   if (tmpfz2 < contact_decision_threshold) {
01300     ret_zmp = act_zmp;
01301     return false; // in the air
01302   } else {
01303     ret_zmp = hrp::Vector3(tmpzmpx / tmpfz, tmpzmpy / tmpfz, zmp_z);
01304     return true; // on ground
01305   }
01306 };
01307 
01308 void Stabilizer::calcStateForEmergencySignal()
01309 {
01310   // COP Check
01311   bool is_cop_outside = false;
01312   if (DEBUGP) {
01313       std::cerr << "[" << m_profile.instance_name << "] Check Emergency State (seq = " << (is_seq_interpolating?"interpolating":"empty") << ")" << std::endl;
01314   }
01315   if (on_ground && transition_count == 0 && control_mode == MODE_ST) {
01316     if (DEBUGP) {
01317         std::cerr << "[" << m_profile.instance_name << "] COP check" << std::endl;
01318     }
01319     for (size_t i = 0; i < stikp.size(); i++) {
01320       if (stikp[i].ee_name.find("leg") == std::string::npos) continue;
01321       // check COP inside
01322       if (m_COPInfo.data[i*3+2] > 20.0 ) {
01323         hrp::Vector3 tmpcop(m_COPInfo.data[i*3+1]/m_COPInfo.data[i*3+2], m_COPInfo.data[i*3]/m_COPInfo.data[i*3+2], 0);
01324         is_cop_outside = is_cop_outside ||
01325             (!szd->is_inside_foot(tmpcop, stikp[i].ee_name=="lleg", cop_check_margin) ||
01326              szd->is_front_of_foot(tmpcop, cop_check_margin) ||
01327              szd->is_rear_of_foot(tmpcop, cop_check_margin));
01328         if (DEBUGP) {
01329             std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[i].ee_name << "] "
01330                       << "outside(" << !szd->is_inside_foot(tmpcop, stikp[i].ee_name=="lleg", cop_check_margin) << ") "
01331                       << "front(" << szd->is_front_of_foot(tmpcop, cop_check_margin) << ") "
01332                       << "rear(" << szd->is_rear_of_foot(tmpcop, cop_check_margin) << ")" << std::endl;
01333         }
01334       } else {
01335         is_cop_outside = true;
01336       }
01337     }
01338   } else {
01339     is_cop_outside = false;
01340   }
01341   // CP Check
01342   bool is_cp_outside = false;
01343   if (on_ground && transition_count == 0 && control_mode == MODE_ST) {
01344     Eigen::Vector2d tmp_cp = act_cp.head(2);
01345     szd->get_margined_vertices(margined_support_polygon_vetices);
01346     szd->calc_convex_hull(margined_support_polygon_vetices, act_contact_states, rel_ee_pos, rel_ee_rot);
01347     if (!is_walking || is_estop_while_walking) is_cp_outside = !szd->is_inside_support_polygon(tmp_cp, - sbp_cog_offset);
01348     if (DEBUGP) {
01349       std::cerr << "[" << m_profile.instance_name << "] CP value " << "[" << act_cp(0) << "," << act_cp(1) << "] [m], "
01350                 << "sbp cog offset [" << sbp_cog_offset(0) << " " << sbp_cog_offset(1) << "], outside ? "
01351                 << (is_cp_outside?"Outside":"Inside")
01352                 << std::endl;
01353     }
01354     if (is_cp_outside) {
01355       if (initial_cp_too_large_error || loop % static_cast <int>(0.2/dt) == 0 ) { // once per 0.2[s]
01356         std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm
01357                   << "] CP too large error " << "[" << act_cp(0) << "," << act_cp(1) << "] [m]" << std::endl;
01358       }
01359       initial_cp_too_large_error = false;
01360     } else {
01361       initial_cp_too_large_error = true;
01362     }
01363   }
01364   // tilt Check
01365   hrp::Vector3 fall_direction = hrp::Vector3::Zero();
01366   bool is_falling = false, will_fall = false;
01367   {
01368       double total_force = 0.0;
01369       for (size_t i = 0; i < stikp.size(); i++) {
01370           if (is_zmp_calc_enable[i]) {
01371               if (is_walking) {
01372                   if (projected_normal.at(i).norm() > sin(tilt_margin[0])) {
01373                       will_fall = true;
01374                       if (m_will_fall_counter[i] % static_cast <int>(1.0/dt) == 0 ) { // once per 1.0[s]
01375                           std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm
01376                                     << "] " << stikp[i].ee_name << " cannot support total weight, "
01377                                     << "swgsuptime : " << m_controlSwingSupportTime.data[i] << ", state : " << ref_contact_states[i]
01378                                     << ", otherwise robot will fall down toward " << "(" << projected_normal.at(i)(0) << "," << projected_normal.at(i)(1) << ") direction" << std::endl;
01379                       }
01380                       m_will_fall_counter[i]++;
01381                   } else {
01382                       m_will_fall_counter[i] = 0;
01383                   }
01384               }
01385               fall_direction += projected_normal.at(i) * act_force.at(i).norm();
01386               total_force += act_force.at(i).norm();
01387           }
01388       }
01389       if (on_ground && transition_count == 0 && control_mode == MODE_ST) {
01390           fall_direction = fall_direction / total_force;
01391       } else {
01392           fall_direction = hrp::Vector3::Zero();
01393       }
01394       if (fall_direction.norm() > sin(tilt_margin[1])) {
01395           is_falling = true;
01396           if (m_is_falling_counter % static_cast <int>(0.2/dt) == 0) { // once per 0.2[s]
01397               std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm
01398                         << "] robot is falling down toward " << "(" << fall_direction(0) << "," << fall_direction(1) << ") direction" << std::endl;
01399           }
01400           m_is_falling_counter++;
01401       } else {
01402           m_is_falling_counter = 0;
01403       }
01404   }
01405   // Total check for emergency signal
01406   switch (emergency_check_mode) {
01407   case OpenHRP::StabilizerService::NO_CHECK:
01408       is_emergency = false;
01409       break;
01410   case OpenHRP::StabilizerService::COP:
01411       is_emergency = is_cop_outside && is_seq_interpolating;
01412       break;
01413   case OpenHRP::StabilizerService::CP:
01414       is_emergency = is_cp_outside;
01415       break;
01416   case OpenHRP::StabilizerService::TILT:
01417       is_emergency = will_fall || is_falling;
01418       break;
01419   default:
01420       break;
01421   }
01422   if (DEBUGP) {
01423       std::cerr << "[" << m_profile.instance_name << "] EmergencyCheck ("
01424                 << (emergency_check_mode == OpenHRP::StabilizerService::NO_CHECK?"NO_CHECK": (emergency_check_mode == OpenHRP::StabilizerService::COP?"COP":"CP") )
01425                 << ") " << (is_emergency?"emergency":"non-emergency") << std::endl;
01426   }
01427   rel_ee_pos.clear();
01428   rel_ee_rot.clear();
01429   rel_ee_name.clear();
01430 };
01431 
01432 void Stabilizer::moveBasePosRotForBodyRPYControl ()
01433 {
01434     // Body rpy control
01435     //   Basically Equation (1) and (2) in the paper [1]
01436     hrp::Vector3 ref_root_rpy = hrp::rpyFromRot(target_root_R);
01437     bool is_root_rot_limit = false;
01438     for (size_t i = 0; i < 2; i++) {
01439         d_rpy[i] = transition_smooth_gain * (eefm_body_attitude_control_gain[i] * (ref_root_rpy(i) - act_base_rpy(i)) - 1/eefm_body_attitude_control_time_const[i] * d_rpy[i]) * dt + d_rpy[i];
01440         d_rpy[i] = vlimit(d_rpy[i], -1 * root_rot_compensation_limit[i], root_rot_compensation_limit[i]);
01441         is_root_rot_limit = is_root_rot_limit || (std::fabs(std::fabs(d_rpy[i]) - root_rot_compensation_limit[i] ) < 1e-5); // near the limit
01442     }
01443     rats::rotm3times(current_root_R, target_root_R, hrp::rotFromRpy(d_rpy[0], d_rpy[1], 0));
01444     m_robot->rootLink()->R = current_root_R;
01445     m_robot->rootLink()->p = target_root_p + target_root_R * rel_cog - current_root_R * rel_cog;
01446     m_robot->calcForwardKinematics();
01447     current_base_rpy = hrp::rpyFromRot(m_robot->rootLink()->R);
01448     current_base_pos = m_robot->rootLink()->p;
01449     if ( DEBUGP || (is_root_rot_limit && loop%200==0) ) {
01450         std::cerr << "[" << m_profile.instance_name << "] Root rot control" << std::endl;
01451         if (is_root_rot_limit) std::cerr << "[" << m_profile.instance_name << "]   Root rot limit reached!!" << std::endl;
01452         std::cerr << "[" << m_profile.instance_name << "]   ref = [" << rad2deg(ref_root_rpy(0)) << " " << rad2deg(ref_root_rpy(1)) << "], "
01453                   << "act = [" << rad2deg(act_base_rpy(0)) << " " << rad2deg(act_base_rpy(1)) << "], "
01454                   << "cur = [" << rad2deg(current_base_rpy(0)) << " " << rad2deg(current_base_rpy(1)) << "], "
01455                   << "limit = [" << rad2deg(root_rot_compensation_limit[0]) << " " << rad2deg(root_rot_compensation_limit[1]) << "][deg]" << std::endl;
01456     }
01457 };
01458 
01459 void Stabilizer::calcSwingSupportLimbGain ()
01460 {
01461     for (size_t i = 0; i < stikp.size(); i++) {
01462         STIKParam& ikp = stikp[i];
01463         if (ref_contact_states[i]) { // Support
01464             // Limit too large support time increment. Max time is 3600.0[s] = 1[h], this assumes that robot's one step time is smaller than 1[h].
01465             ikp.support_time = std::min(3600.0, ikp.support_time+dt);
01466             // In some PC, does not work because the first line is optimized out.
01467             // ikp.support_time += dt;
01468             // ikp.support_time = std::min(3600.0, ikp.support_time);
01469             if (ikp.support_time > eefm_pos_transition_time) {
01470                 ikp.swing_support_gain = (m_controlSwingSupportTime.data[i] / eefm_pos_transition_time);
01471             } else {
01472                 ikp.swing_support_gain = (ikp.support_time / eefm_pos_transition_time);
01473             }
01474             ikp.swing_support_gain = std::max(0.0, std::min(1.0, ikp.swing_support_gain));
01475         } else { // Swing
01476             ikp.swing_support_gain = 0.0;
01477             ikp.support_time = 0.0;
01478         }
01479     }
01480     if (DEBUGP) {
01481         std::cerr << "[" << m_profile.instance_name << "] SwingSupportLimbGain = [";
01482         for (size_t i = 0; i < stikp.size(); i++) std::cerr << stikp[i].swing_support_gain << " ";
01483         std::cerr << "], ref_contact_states = [";
01484         for (size_t i = 0; i < stikp.size(); i++) std::cerr << ref_contact_states[i] << " ";
01485         std::cerr << "], sstime = [";
01486         for (size_t i = 0; i < stikp.size(); i++) std::cerr << m_controlSwingSupportTime.data[i] << " ";
01487         std::cerr << "], toeheel_ratio = [";
01488         for (size_t i = 0; i < stikp.size(); i++) std::cerr << toeheel_ratio[i] << " ";
01489         std::cerr << "], support_time = [";
01490         for (size_t i = 0; i < stikp.size(); i++) std::cerr << stikp[i].support_time << " ";
01491         std::cerr << "]" << std::endl;
01492     }
01493 }
01494 
01495 void Stabilizer::calcTPCC() {
01496     // stabilizer loop
01497       // Choi's feedback law
01498       hrp::Vector3 cog = m_robot->calcCM();
01499       hrp::Vector3 newcog = hrp::Vector3::Zero();
01500       hrp::Vector3 dcog(ref_cog - act_cog);
01501       hrp::Vector3 dzmp(ref_zmp - act_zmp);
01502       for (size_t i = 0; i < 2; i++) {
01503         double uu = ref_cogvel(i) - k_tpcc_p[i] * transition_smooth_gain * dzmp(i)
01504                                   + k_tpcc_x[i] * transition_smooth_gain * dcog(i);
01505         newcog(i) = uu * dt + cog(i);
01506       }
01507 
01508       moveBasePosRotForBodyRPYControl ();
01509 
01510       // target at ee => target at link-origin
01511       hrp::Vector3 target_link_p[stikp.size()];
01512       hrp::Matrix33 target_link_R[stikp.size()];
01513       for (size_t i = 0; i < stikp.size(); i++) {
01514         rats::rotm3times(target_link_R[i], target_ee_R[i], stikp[i].localR.transpose());
01515         target_link_p[i] = target_ee_p[i] - target_ee_R[i] * stikp[i].localCOPPos;
01516       }
01517       // solveIK
01518       //   IK target is link origin pos and rot, not ee pos and rot.
01519       //for (size_t jj = 0; jj < 5; jj++) {
01520       size_t max_ik_loop_count = 0;
01521       for (size_t i = 0; i < stikp.size(); i++) {
01522           if (max_ik_loop_count < stikp[i].ik_loop_count) max_ik_loop_count = stikp[i].ik_loop_count;
01523       }
01524       for (size_t jj = 0; jj < max_ik_loop_count; jj++) {
01525         hrp::Vector3 tmpcm = m_robot->calcCM();
01526         for (size_t i = 0; i < 2; i++) {
01527           m_robot->rootLink()->p(i) = m_robot->rootLink()->p(i) + 0.9 * (newcog(i) - tmpcm(i));
01528         }
01529         m_robot->calcForwardKinematics();
01530         for (size_t i = 0; i < stikp.size(); i++) {
01531           if (is_ik_enable[i]) {
01532               jpe_v[i]->calcInverseKinematics2Loop(target_link_p[i], target_link_R[i], 1.0, stikp[i].avoid_gain, stikp[i].reference_gain, &qrefv, transition_smooth_gain);
01533           }
01534         }
01535       }
01536 }
01537 
01538 
01539 void Stabilizer::calcEEForceMomentControl() {
01540 
01541     // stabilizer loop
01542       // return to referencea
01543       m_robot->rootLink()->R = target_root_R;
01544       m_robot->rootLink()->p = target_root_p;
01545       for ( int i = 0; i < m_robot->numJoints(); i++ ) {
01546         m_robot->joint(i)->q = qrefv[i];
01547       }
01548       for (size_t i = 0; i < jpe_v.size(); i++) {
01549         if (is_ik_enable[i]) {
01550           for ( int j = 0; j < jpe_v[i]->numJoints(); j++ ){
01551             int idx = jpe_v[i]->joint(j)->jointId;
01552             m_robot->joint(idx)->q = qorg[idx];
01553           }
01554         }
01555       }
01556       // Fix for toe joint
01557       for (size_t i = 0; i < jpe_v.size(); i++) {
01558           if (is_ik_enable[i]) {
01559               if (jpe_v[i]->numJoints() == 7) {
01560                   int idx = jpe_v[i]->joint(jpe_v[i]->numJoints() -1)->jointId;
01561                   m_robot->joint(idx)->q = qrefv[idx];
01562               }
01563           }
01564       }
01565 
01566       // State calculation for swing ee compensation
01567       //   joint angle : current control output
01568       //   root pos : target root p
01569       //   root rot : actual root rot
01570       {
01571           // Calc status
01572           m_robot->rootLink()->R = target_root_R;
01573           m_robot->rootLink()->p = target_root_p;
01574           m_robot->calcForwardKinematics();
01575           hrp::Sensor* sen = m_robot->sensor<hrp::RateGyroSensor>("gyrometer");
01576           hrp::Matrix33 senR = sen->link->R * sen->localR;
01577           hrp::Matrix33 act_Rs(hrp::rotFromRpy(m_rpy.data.r, m_rpy.data.p, m_rpy.data.y));
01578           m_robot->rootLink()->R = act_Rs * (senR.transpose() * m_robot->rootLink()->R);
01579           m_robot->calcForwardKinematics();
01580           hrp::Vector3 foot_origin_pos;
01581           hrp::Matrix33 foot_origin_rot;
01582           calcFootOriginCoords (foot_origin_pos, foot_origin_rot);
01583           // Calculate foot_origin_coords-relative ee pos and rot
01584           // Subtract them from target_ee_diff_xx
01585           for (size_t i = 0; i < stikp.size(); i++) {
01586               hrp::Link* target = m_robot->link(stikp[i].target_name);
01587               stikp[i].target_ee_diff_p -= foot_origin_rot.transpose() * (target->p + target->R * stikp[i].localp - foot_origin_pos);
01588               stikp[i].target_ee_diff_r = (foot_origin_rot.transpose() * target->R * stikp[i].localR).transpose() * stikp[i].target_ee_diff_r;
01589           }
01590       }
01591 
01592       // State calculation for control : calculate "current" state
01593       //   joint angle : current control output
01594       //   root pos : target + keep COG against rpy control
01595       //   root rot : target + rpy control
01596       moveBasePosRotForBodyRPYControl ();
01597 
01598       // Convert d_foot_pos in foot origin frame => "current" world frame
01599       hrp::Vector3 foot_origin_pos;
01600       hrp::Matrix33 foot_origin_rot;
01601       calcFootOriginCoords (foot_origin_pos, foot_origin_rot);
01602       std::vector<hrp::Vector3> current_d_foot_pos;
01603       for (size_t i = 0; i < stikp.size(); i++)
01604           current_d_foot_pos.push_back(foot_origin_rot * stikp[i].d_foot_pos);
01605 
01606       // Swing ee compensation.
01607       calcSwingEEModification();
01608 
01609       // solveIK
01610       //   IK target is link origin pos and rot, not ee pos and rot.
01611       std::vector<hrp::Vector3> tmpp(stikp.size());
01612       std::vector<hrp::Matrix33> tmpR(stikp.size());
01613       double tmp_d_pos_z_root = 0.0;
01614       for (size_t i = 0; i < stikp.size(); i++) {
01615         if (is_ik_enable[i]) {
01616           // Add damping_control compensation to target value
01617           if (is_feedback_control_enable[i]) {
01618             rats::rotm3times(tmpR[i], target_ee_R[i], hrp::rotFromRpy(-1*stikp[i].ee_d_foot_rpy));
01619             // foot force difference control version
01620             // total_target_foot_p[i](2) = target_foot_p[i](2) + (i==0?0.5:-0.5)*zctrl;
01621             // foot force independent damping control
01622             tmpp[i] = target_ee_p[i] - current_d_foot_pos[i];
01623           } else {
01624             tmpp[i] = target_ee_p[i];
01625             tmpR[i] = target_ee_R[i];
01626           }
01627           // Add swing ee compensation
01628           rats::rotm3times(tmpR[i], tmpR[i], hrp::rotFromRpy(stikp[i].d_rpy_swing));
01629           tmpp[i] = tmpp[i] + foot_origin_rot * stikp[i].d_pos_swing;
01630         }
01631       }
01632 
01633       limbStretchAvoidanceControl(tmpp ,tmpR);
01634 
01635       // IK
01636       for (size_t i = 0; i < stikp.size(); i++) {
01637         if (is_ik_enable[i]) {
01638           for (size_t jj = 0; jj < stikp[i].ik_loop_count; jj++) {
01639             jpe_v[i]->calcInverseKinematics2Loop(tmpp[i], tmpR[i], 1.0, 0.001, 0.01, &qrefv, transition_smooth_gain,
01640                                                  //stikp[i].localCOPPos;
01641                                                  stikp[i].localp,
01642                                                  stikp[i].localR);
01643           }
01644         }
01645       }
01646 }
01647 
01648 // Swing ee compensation.
01649 //   Calculate compensation values to minimize the difference between "current" foot-origin-coords-relative pos and rot and "target" foot-origin-coords-relative pos and rot for swing ee.
01650 //   Input  : target_ee_diff_p, target_ee_diff_r
01651 //   Output : d_pos_swing, d_rpy_swing
01652 void Stabilizer::calcSwingEEModification ()
01653 {
01654     for (size_t i = 0; i < stikp.size(); i++) {
01655         // Calc compensation values
01656         double limit_pos = 30 * 1e-3; // 30[mm] limit
01657         double limit_rot = deg2rad(10); // 10[deg] limit
01658         if (ref_contact_states[contact_states_index_map[stikp[i].ee_name]] || act_contact_states[contact_states_index_map[stikp[i].ee_name]]) {
01659             // If actual contact or target contact is ON, do not use swing ee compensation. Exponential zero retrieving.
01660             stikp[i].d_rpy_swing = calcDampingControl(stikp[i].d_rpy_swing, stikp[i].eefm_swing_rot_time_const);
01661             stikp[i].d_pos_swing = calcDampingControl(stikp[i].d_pos_swing, stikp[i].eefm_swing_pos_time_const);
01662             stikp[i].target_ee_diff_p_filter->reset(stikp[i].d_pos_swing);
01663             stikp[i].target_ee_diff_r_filter->reset(stikp[i].d_rpy_swing);
01664         } else {
01665             /* position */
01666             {
01667                 hrp::Vector3 tmpdiffp = stikp[i].eefm_swing_pos_spring_gain.cwiseProduct(stikp[i].target_ee_diff_p_filter->passFilter(stikp[i].target_ee_diff_p));
01668                 double lvlimit = -50 * 1e-3 * dt, uvlimit = 50 * 1e-3 * dt; // 50 [mm/s]
01669                 hrp::Vector3 limit_by_lvlimit = stikp[i].prev_d_pos_swing + lvlimit * hrp::Vector3::Ones();
01670                 hrp::Vector3 limit_by_uvlimit = stikp[i].prev_d_pos_swing + uvlimit * hrp::Vector3::Ones();
01671                 stikp[i].d_pos_swing = vlimit(vlimit(tmpdiffp, -1 * limit_pos, limit_pos), limit_by_lvlimit, limit_by_uvlimit);
01672             }
01673             /* rotation */
01674             {
01675                 hrp::Vector3 tmpdiffr = stikp[i].eefm_swing_rot_spring_gain.cwiseProduct(stikp[i].target_ee_diff_r_filter->passFilter(hrp::rpyFromRot(stikp[i].target_ee_diff_r)));
01676                 double lvlimit = deg2rad(-20.0*dt), uvlimit = deg2rad(20.0*dt); // 20 [deg/s]
01677                 hrp::Vector3 limit_by_lvlimit = stikp[i].prev_d_rpy_swing + lvlimit * hrp::Vector3::Ones();
01678                 hrp::Vector3 limit_by_uvlimit = stikp[i].prev_d_rpy_swing + uvlimit * hrp::Vector3::Ones();
01679                 stikp[i].d_rpy_swing = vlimit(vlimit(tmpdiffr, -1 * limit_rot, limit_rot), limit_by_lvlimit, limit_by_uvlimit);
01680             }
01681         }
01682         stikp[i].prev_d_pos_swing = stikp[i].d_pos_swing;
01683         stikp[i].prev_d_rpy_swing = stikp[i].d_rpy_swing;
01684     }
01685     if (DEBUGP) {
01686         std::cerr << "[" << m_profile.instance_name << "] Swing foot control" << std::endl;
01687         for (size_t i = 0; i < stikp.size(); i++) {
01688             std::cerr << "[" << m_profile.instance_name << "]   "
01689                       << "d_rpy_swing (" << stikp[i].ee_name << ")  = " << (stikp[i].d_rpy_swing / M_PI * 180.0).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[deg], "
01690                       << "d_pos_swing (" << stikp[i].ee_name << ")  = " << (stikp[i].d_pos_swing * 1e3).format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[mm]" << std::endl;
01691         }
01692     }
01693 };
01694 
01695 void Stabilizer::limbStretchAvoidanceControl (const std::vector<hrp::Vector3>& ee_p, const std::vector<hrp::Matrix33>& ee_R)
01696 {
01697   double tmp_d_pos_z_root = 0.0, prev_d_pos_z_root = d_pos_z_root;
01698   if (use_limb_stretch_avoidance) {
01699     for (size_t i = 0; i < stikp.size(); i++) {
01700       if (is_ik_enable[i]) {
01701         // Check whether inside limb length limitation
01702         hrp::Link* parent_link = m_robot->link(stikp[i].parent_name);
01703         hrp::Vector3 targetp = (ee_p[i] - ee_R[i] * stikp[i].localR.transpose() * stikp[i].localp) - parent_link->p; // position from parent to target link (world frame)
01704         double limb_length_limitation = stikp[i].max_limb_length - stikp[i].limb_length_margin;
01705         double tmp = limb_length_limitation * limb_length_limitation - targetp(0) * targetp(0) - targetp(1) * targetp(1);
01706         if (targetp.norm() > limb_length_limitation && tmp >= 0) {
01707           tmp_d_pos_z_root = std::min(tmp_d_pos_z_root, targetp(2) + std::sqrt(tmp));
01708         }
01709       }
01710     }
01711     // Change root link height depending on limb length
01712     d_pos_z_root = tmp_d_pos_z_root == 0.0 ? calcDampingControl(d_pos_z_root, limb_stretch_avoidance_time_const) : tmp_d_pos_z_root;
01713   } else {
01714     d_pos_z_root = calcDampingControl(d_pos_z_root, limb_stretch_avoidance_time_const);
01715   }
01716   d_pos_z_root = vlimit(d_pos_z_root, prev_d_pos_z_root + limb_stretch_avoidance_vlimit[0], prev_d_pos_z_root + limb_stretch_avoidance_vlimit[1]);
01717   m_robot->rootLink()->p(2) += d_pos_z_root;
01718 }
01719 
01720 // Damping control functions
01721 //   Basically Equation (14) in the paper [1]
01722 double Stabilizer::calcDampingControl (const double tau_d, const double tau, const double prev_d,
01723                                        const double DD, const double TT)
01724 {
01725   return (1/DD * (tau_d - tau) - 1/TT * prev_d) * dt + prev_d;
01726 };
01727 
01728 // Retrieving only
01729 hrp::Vector3 Stabilizer::calcDampingControl (const hrp::Vector3& prev_d, const hrp::Vector3& TT)
01730 {
01731   return (- prev_d.cwiseQuotient(TT)) * dt + prev_d;
01732 };
01733 
01734 // Retrieving only
01735 double Stabilizer::calcDampingControl (const double prev_d, const double TT)
01736 {
01737   return - 1/TT * prev_d * dt + prev_d;
01738 };
01739 
01740 hrp::Vector3 Stabilizer::calcDampingControl (const hrp::Vector3& tau_d, const hrp::Vector3& tau, const hrp::Vector3& prev_d,
01741                                              const hrp::Vector3& DD, const hrp::Vector3& TT)
01742 {
01743   return ((tau_d - tau).cwiseQuotient(DD) - prev_d.cwiseQuotient(TT)) * dt + prev_d;
01744 };
01745 
01746 void Stabilizer::calcDiffFootOriginExtMoment ()
01747 {
01748     // calc reference ext moment around foot origin pos
01749     // static const double grav = 9.80665; /* [m/s^2] */
01750     double mg = total_mass * eefm_gravitational_acceleration;
01751     hrp::Vector3 ref_ext_moment = hrp::Vector3(mg * ref_cog(1) - ref_total_foot_origin_moment(0),
01752                                                -mg * ref_cog(0) - ref_total_foot_origin_moment(1),
01753                                                0);
01754     // calc act ext moment around foot origin pos
01755     hrp::Vector3 act_ext_moment = hrp::Vector3(mg * act_cog(1) - act_total_foot_origin_moment(0),
01756                                                -mg * act_cog(0) - act_total_foot_origin_moment(1),
01757                                                0);
01758     // Do not calculate actual value if in the air, because of invalid act_zmp.
01759     if ( !on_ground ) act_ext_moment = ref_ext_moment;
01760     // Calc diff
01761     diff_foot_origin_ext_moment = ref_ext_moment - act_ext_moment;
01762     if (DEBUGP) {
01763         std::cerr << "[" << m_profile.instance_name << "] DiffStaticBalancePointOffset" << std::endl;
01764         std::cerr << "[" << m_profile.instance_name << "]   "
01765                   << "ref_ext_moment = " << ref_ext_moment.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[mm], "
01766                   << "act_ext_moment = " << act_ext_moment.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[mm], "
01767                   << "diff ext_moment = " << diff_foot_origin_ext_moment.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[mm]" << std::endl;
01768     }
01769 };
01770 
01771 /*
01772 RTC::ReturnCode_t Stabilizer::onAborting(RTC::UniqueId ec_id)
01773 {
01774   return RTC::RTC_OK;
01775 }
01776 */
01777 
01778 /*
01779 RTC::ReturnCode_t Stabilizer::onError(RTC::UniqueId ec_id)
01780 {
01781   return RTC::RTC_OK;
01782 }
01783 */
01784 
01785 /*
01786 RTC::ReturnCode_t Stabilizer::onReset(RTC::UniqueId ec_id)
01787 {
01788   return RTC::RTC_OK;
01789 }
01790 */
01791 
01792 /*
01793 RTC::ReturnCode_t Stabilizer::onStateUpdate(RTC::UniqueId ec_id)
01794 {
01795   return RTC::RTC_OK;
01796 }
01797 */
01798 
01799 /*
01800 RTC::ReturnCode_t Stabilizer::onRateChanged(RTC::UniqueId ec_id)
01801 {
01802   return RTC::RTC_OK;
01803 }
01804 */
01805 
01806 void Stabilizer::sync_2_st ()
01807 {
01808   std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm
01809             << "] Sync IDLE => ST"  << std::endl;
01810   pangx_ref = pangy_ref = pangx = pangy = 0;
01811   rdx = rdy = rx = ry = 0;
01812   d_rpy[0] = d_rpy[1] = 0;
01813   pdr = hrp::Vector3::Zero();
01814   pos_ctrl = hrp::Vector3::Zero();
01815   for (size_t i = 0; i < stikp.size(); i++) {
01816     STIKParam& ikp = stikp[i];
01817     ikp.target_ee_diff_p = hrp::Vector3::Zero();
01818     ikp.target_ee_diff_r = hrp::Matrix33::Identity();
01819     ikp.d_pos_swing = ikp.prev_d_pos_swing = hrp::Vector3::Zero();
01820     ikp.d_rpy_swing = ikp.prev_d_rpy_swing = hrp::Vector3::Zero();
01821     ikp.target_ee_diff_p_filter->reset(hrp::Vector3::Zero());
01822     ikp.target_ee_diff_r_filter->reset(hrp::Vector3::Zero());
01823     ikp.d_foot_pos = ikp.d_foot_rpy = ikp.ee_d_foot_rpy = hrp::Vector3::Zero();
01824   }
01825   if (on_ground) {
01826     transition_count = -1 * calcMaxTransitionCount();
01827     control_mode = MODE_ST;
01828   } else {
01829     transition_count = 0;
01830     control_mode = MODE_AIR;
01831   }
01832 }
01833 
01834 void Stabilizer::sync_2_idle ()
01835 {
01836   std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm
01837             << "] Sync ST => IDLE"  << std::endl;
01838   transition_count = calcMaxTransitionCount();
01839   for (int i = 0; i < m_robot->numJoints(); i++ ) {
01840     transition_joint_q[i] = m_robot->joint(i)->q;
01841   }
01842 }
01843 
01844 void Stabilizer::startStabilizer(void)
01845 {
01846     waitSTTransition(); // Wait until all transition has finished
01847     {
01848         Guard guard(m_mutex);
01849         if ( control_mode == MODE_IDLE ) {
01850             std::cerr << "[" << m_profile.instance_name << "] " << "Start ST"  << std::endl;
01851             sync_2_st();
01852         }
01853     }
01854     waitSTTransition();
01855     std::cerr << "[" << m_profile.instance_name << "] " << "Start ST DONE"  << std::endl;
01856 }
01857 
01858 void Stabilizer::stopStabilizer(void)
01859 {
01860     waitSTTransition(); // Wait until all transition has finished
01861     {
01862         Guard guard(m_mutex);
01863         if ( (control_mode == MODE_ST || control_mode == MODE_AIR) ) {
01864             std::cerr << "[" << m_profile.instance_name << "] " << "Stop ST"  << std::endl;
01865             control_mode = (control_mode == MODE_ST) ? MODE_SYNC_TO_IDLE : MODE_IDLE;
01866         }
01867     }
01868     waitSTTransition();
01869     std::cerr << "[" << m_profile.instance_name << "] " << "Stop ST DONE"  << std::endl;
01870 }
01871 
01872 void Stabilizer::getParameter(OpenHRP::StabilizerService::stParam& i_stp)
01873 {
01874   std::cerr << "[" << m_profile.instance_name << "] getParameter" << std::endl;
01875   for (size_t i = 0; i < 2; i++) {
01876     // i_stp.k_run_b[i] = k_run_b[i];
01877     // i_stp.d_run_b[i] = d_run_b[i];
01878     //m_tau_x[i].setup(i_stp.tdfke[0], i_stp.tdftc[0], dt);
01879     //m_tau_y[i].setup(i_stp.tdfke[0], i_stp.tdftc[0], dt);
01880     //m_f_z.setup(i_stp.tdfke[1], i_stp.tdftc[1], dt);
01881     i_stp.k_tpcc_p[i] = k_tpcc_p[i];
01882     i_stp.k_tpcc_x[i] = k_tpcc_x[i];
01883     i_stp.k_brot_p[i] = k_brot_p[i];
01884     i_stp.k_brot_tc[i] = k_brot_tc[i];
01885   }
01886   // i_stp.k_run_x = m_torque_k[0];
01887   // i_stp.k_run_y = m_torque_k[1];
01888   // i_stp.d_run_x = m_torque_d[0];
01889   // i_stp.d_run_y = m_torque_d[1];
01890   for (size_t i = 0; i < 2; i++) {
01891     i_stp.eefm_k1[i] = eefm_k1[i];
01892     i_stp.eefm_k2[i] = eefm_k2[i];
01893     i_stp.eefm_k3[i] = eefm_k3[i];
01894     i_stp.eefm_zmp_delay_time_const[i] = eefm_zmp_delay_time_const[i];
01895     i_stp.eefm_ref_zmp_aux[i] = ref_zmp_aux(i);
01896     i_stp.eefm_body_attitude_control_time_const[i] = eefm_body_attitude_control_time_const[i];
01897     i_stp.eefm_body_attitude_control_gain[i] = eefm_body_attitude_control_gain[i];
01898     i_stp.ref_capture_point[i] = ref_cp(i);
01899     i_stp.act_capture_point[i] = act_cp(i);
01900     i_stp.cp_offset[i] = cp_offset(i);
01901   }
01902   i_stp.eefm_pos_time_const_support.length(stikp.size());
01903   i_stp.eefm_pos_damping_gain.length(stikp.size());
01904   i_stp.eefm_pos_compensation_limit.length(stikp.size());
01905   i_stp.eefm_swing_pos_spring_gain.length(stikp.size());
01906   i_stp.eefm_swing_pos_time_const.length(stikp.size());
01907   i_stp.eefm_rot_time_const.length(stikp.size());
01908   i_stp.eefm_rot_damping_gain.length(stikp.size());
01909   i_stp.eefm_rot_compensation_limit.length(stikp.size());
01910   i_stp.eefm_swing_rot_spring_gain.length(stikp.size());
01911   i_stp.eefm_swing_rot_time_const.length(stikp.size());
01912   i_stp.eefm_ee_moment_limit.length(stikp.size());
01913   i_stp.eefm_ee_forcemoment_distribution_weight.length(stikp.size());
01914   for (size_t j = 0; j < stikp.size(); j++) {
01915       i_stp.eefm_pos_damping_gain[j].length(3);
01916       i_stp.eefm_pos_time_const_support[j].length(3);
01917       i_stp.eefm_swing_pos_spring_gain[j].length(3);
01918       i_stp.eefm_swing_pos_time_const[j].length(3);
01919       i_stp.eefm_rot_damping_gain[j].length(3);
01920       i_stp.eefm_rot_time_const[j].length(3);
01921       i_stp.eefm_swing_rot_spring_gain[j].length(3);
01922       i_stp.eefm_swing_rot_time_const[j].length(3);
01923       i_stp.eefm_ee_moment_limit[j].length(3);
01924       i_stp.eefm_ee_forcemoment_distribution_weight[j].length(6);
01925       for (size_t i = 0; i < 3; i++) {
01926           i_stp.eefm_pos_damping_gain[j][i] = stikp[j].eefm_pos_damping_gain(i);
01927           i_stp.eefm_pos_time_const_support[j][i] = stikp[j].eefm_pos_time_const_support(i);
01928           i_stp.eefm_swing_pos_spring_gain[j][i] = stikp[j].eefm_swing_pos_spring_gain(i);
01929           i_stp.eefm_swing_pos_time_const[j][i] = stikp[j].eefm_swing_pos_time_const(i);
01930           i_stp.eefm_rot_damping_gain[j][i] = stikp[j].eefm_rot_damping_gain(i);
01931           i_stp.eefm_rot_time_const[j][i] = stikp[j].eefm_rot_time_const(i);
01932           i_stp.eefm_swing_rot_spring_gain[j][i] = stikp[j].eefm_swing_rot_spring_gain(i);
01933           i_stp.eefm_swing_rot_time_const[j][i] = stikp[j].eefm_swing_rot_time_const(i);
01934           i_stp.eefm_ee_moment_limit[j][i] = stikp[j].eefm_ee_moment_limit(i);
01935           i_stp.eefm_ee_forcemoment_distribution_weight[j][i] = stikp[j].eefm_ee_forcemoment_distribution_weight(i);
01936           i_stp.eefm_ee_forcemoment_distribution_weight[j][i+3] = stikp[j].eefm_ee_forcemoment_distribution_weight(i+3);
01937       }
01938       i_stp.eefm_pos_compensation_limit[j] = stikp[j].eefm_pos_compensation_limit;
01939       i_stp.eefm_rot_compensation_limit[j] = stikp[j].eefm_rot_compensation_limit;
01940   }
01941   for (size_t i = 0; i < 3; i++) {
01942     i_stp.eefm_swing_pos_damping_gain[i] = eefm_swing_pos_damping_gain(i);
01943     i_stp.eefm_swing_rot_damping_gain[i] = eefm_swing_rot_damping_gain(i);
01944   }
01945   i_stp.eefm_pos_time_const_swing = eefm_pos_time_const_swing;
01946   i_stp.eefm_pos_transition_time = eefm_pos_transition_time;
01947   i_stp.eefm_pos_margin_time = eefm_pos_margin_time;
01948   i_stp.eefm_leg_inside_margin = szd->get_leg_inside_margin();
01949   i_stp.eefm_leg_outside_margin = szd->get_leg_outside_margin();
01950   i_stp.eefm_leg_front_margin = szd->get_leg_front_margin();
01951   i_stp.eefm_leg_rear_margin = szd->get_leg_rear_margin();
01952 
01953   std::vector<std::vector<Eigen::Vector2d> > support_polygon_vec;
01954   szd->get_vertices(support_polygon_vec);
01955   i_stp.eefm_support_polygon_vertices_sequence.length(support_polygon_vec.size());
01956   for (size_t ee_idx = 0; ee_idx < support_polygon_vec.size(); ee_idx++) {
01957       i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices.length(support_polygon_vec[ee_idx].size());
01958       for (size_t v_idx = 0; v_idx < support_polygon_vec[ee_idx].size(); v_idx++) {
01959           i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices[v_idx].pos[0] = support_polygon_vec[ee_idx][v_idx](0);
01960           i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices[v_idx].pos[1] = support_polygon_vec[ee_idx][v_idx](1);
01961       }
01962   }
01963 
01964   i_stp.eefm_cogvel_cutoff_freq = act_cogvel_filter->getCutOffFreq();
01965   i_stp.eefm_wrench_alpha_blending = szd->get_wrench_alpha_blending();
01966   i_stp.eefm_alpha_cutoff_freq = szd->get_alpha_cutoff_freq();
01967   i_stp.eefm_gravitational_acceleration = eefm_gravitational_acceleration;
01968   i_stp.eefm_ee_error_cutoff_freq = stikp[0].target_ee_diff_p_filter->getCutOffFreq();
01969   i_stp.eefm_use_force_difference_control = eefm_use_force_difference_control;
01970   i_stp.eefm_use_swing_damping = eefm_use_swing_damping;
01971   for (size_t i = 0; i < 3; ++i) {
01972       i_stp.eefm_swing_damping_force_thre[i] = eefm_swing_damping_force_thre[i];
01973       i_stp.eefm_swing_damping_moment_thre[i] = eefm_swing_damping_moment_thre[i];
01974   }
01975   i_stp.is_ik_enable.length(is_ik_enable.size());
01976   for (size_t i = 0; i < is_ik_enable.size(); i++) {
01977       i_stp.is_ik_enable[i] = is_ik_enable[i];
01978   }
01979   i_stp.is_feedback_control_enable.length(is_feedback_control_enable.size());
01980   for (size_t i = 0; i < is_feedback_control_enable.size(); i++) {
01981       i_stp.is_feedback_control_enable[i] = is_feedback_control_enable[i];
01982   }
01983   i_stp.is_zmp_calc_enable.length(is_zmp_calc_enable.size());
01984   for (size_t i = 0; i < is_zmp_calc_enable.size(); i++) {
01985       i_stp.is_zmp_calc_enable[i] = is_zmp_calc_enable[i];
01986   }
01987 
01988   i_stp.foot_origin_offset.length(2);
01989   for (size_t i = 0; i < i_stp.foot_origin_offset.length(); i++) {
01990       i_stp.foot_origin_offset[i].length(3);
01991       i_stp.foot_origin_offset[i][0] = foot_origin_offset[i](0);
01992       i_stp.foot_origin_offset[i][1] = foot_origin_offset[i](1);
01993       i_stp.foot_origin_offset[i][2] = foot_origin_offset[i](2);
01994   }
01995   i_stp.st_algorithm = st_algorithm;
01996   i_stp.transition_time = transition_time;
01997   i_stp.cop_check_margin = cop_check_margin;
01998   for (size_t i = 0; i < cp_check_margin.size(); i++) {
01999     i_stp.cp_check_margin[i] = cp_check_margin[i];
02000   }
02001   for (size_t i = 0; i < tilt_margin.size(); i++) {
02002     i_stp.tilt_margin[i] = tilt_margin[i];
02003   }
02004   i_stp.contact_decision_threshold = contact_decision_threshold;
02005   i_stp.is_estop_while_walking = is_estop_while_walking;
02006   switch(control_mode) {
02007   case MODE_IDLE: i_stp.controller_mode = OpenHRP::StabilizerService::MODE_IDLE; break;
02008   case MODE_AIR: i_stp.controller_mode = OpenHRP::StabilizerService::MODE_AIR; break;
02009   case MODE_ST: i_stp.controller_mode = OpenHRP::StabilizerService::MODE_ST; break;
02010   case MODE_SYNC_TO_IDLE: i_stp.controller_mode = OpenHRP::StabilizerService::MODE_SYNC_TO_IDLE; break;
02011   case MODE_SYNC_TO_AIR: i_stp.controller_mode = OpenHRP::StabilizerService::MODE_SYNC_TO_AIR; break;
02012   default: break;
02013   }
02014   i_stp.emergency_check_mode = emergency_check_mode;
02015   i_stp.end_effector_list.length(stikp.size());
02016   i_stp.use_limb_stretch_avoidance = use_limb_stretch_avoidance;
02017   i_stp.use_zmp_truncation = use_zmp_truncation;
02018   i_stp.limb_stretch_avoidance_time_const = limb_stretch_avoidance_time_const;
02019   i_stp.limb_length_margin.length(stikp.size());
02020   i_stp.detection_time_to_air = detection_count_to_air * dt;
02021   for (size_t i = 0; i < 2; i++) {
02022     i_stp.limb_stretch_avoidance_vlimit[i] = limb_stretch_avoidance_vlimit[i];
02023     i_stp.root_rot_compensation_limit[i] = root_rot_compensation_limit[i];
02024   }
02025   for (size_t i = 0; i < stikp.size(); i++) {
02026       const rats::coordinates cur_ee = rats::coordinates(stikp.at(i).localp, stikp.at(i).localR);
02027       OpenHRP::AutoBalancerService::Footstep ret_ee;
02028       // position
02029       memcpy(ret_ee.pos, cur_ee.pos.data(), sizeof(double)*3);
02030       // rotation
02031       Eigen::Quaternion<double> qt(cur_ee.rot);
02032       ret_ee.rot[0] = qt.w();
02033       ret_ee.rot[1] = qt.x();
02034       ret_ee.rot[2] = qt.y();
02035       ret_ee.rot[3] = qt.z();
02036       // name
02037       ret_ee.leg = stikp.at(i).ee_name.c_str();
02038       // set
02039       i_stp.end_effector_list[i] = ret_ee;
02040       i_stp.limb_length_margin[i] = stikp[i].limb_length_margin;
02041   }
02042   i_stp.ik_limb_parameters.length(jpe_v.size());
02043   for (size_t i = 0; i < jpe_v.size(); i++) {
02044       OpenHRP::StabilizerService::IKLimbParameters& ilp = i_stp.ik_limb_parameters[i];
02045       ilp.ik_optional_weight_vector.length(jpe_v[i]->numJoints());
02046       std::vector<double> ov;
02047       ov.resize(jpe_v[i]->numJoints());
02048       jpe_v[i]->getOptionalWeightVector(ov);
02049       for (size_t j = 0; j < jpe_v[i]->numJoints(); j++) {
02050           ilp.ik_optional_weight_vector[j] = ov[j];
02051       }
02052       ilp.sr_gain = jpe_v[i]->getSRGain();
02053       ilp.avoid_gain = stikp[i].avoid_gain;
02054       ilp.reference_gain = stikp[i].reference_gain;
02055       ilp.manipulability_limit = jpe_v[i]->getManipulabilityLimit();
02056       ilp.ik_loop_count = stikp[i].ik_loop_count; // size_t -> unsigned short, value may change, but ik_loop_count is small value and value not change
02057   }
02058 };
02059 
02060 void Stabilizer::setParameter(const OpenHRP::StabilizerService::stParam& i_stp)
02061 {
02062   Guard guard(m_mutex);
02063   std::cerr << "[" << m_profile.instance_name << "] setParameter" << std::endl;
02064   for (size_t i = 0; i < 2; i++) {
02065     k_tpcc_p[i] = i_stp.k_tpcc_p[i];
02066     k_tpcc_x[i] = i_stp.k_tpcc_x[i];
02067     k_brot_p[i] = i_stp.k_brot_p[i];
02068     k_brot_tc[i] = i_stp.k_brot_tc[i];
02069   }
02070   std::cerr << "[" << m_profile.instance_name << "]  TPCC" << std::endl;
02071   std::cerr << "[" << m_profile.instance_name << "]   k_tpcc_p  = [" << k_tpcc_p[0] << ", " <<  k_tpcc_p[1] << "], k_tpcc_x  = [" << k_tpcc_x[0] << ", " << k_tpcc_x[1] << "], k_brot_p  = [" << k_brot_p[0] << ", " << k_brot_p[1] << "], k_brot_tc = [" << k_brot_tc[0] << ", " << k_brot_tc[1] << "]" << std::endl;
02072   // for (size_t i = 0; i < 2; i++) {
02073   //   k_run_b[i] = i_stp.k_run_b[i];
02074   //   d_run_b[i] = i_stp.d_run_b[i];
02075   //   m_tau_x[i].setup(i_stp.tdfke[0], i_stp.tdftc[0], dt);
02076   //   m_tau_y[i].setup(i_stp.tdfke[0], i_stp.tdftc[0], dt);
02077   //   m_f_z.setup(i_stp.tdfke[1], i_stp.tdftc[1], dt);
02078   // }
02079   // m_torque_k[0] = i_stp.k_run_x;
02080   // m_torque_k[1] = i_stp.k_run_y;
02081   // m_torque_d[0] = i_stp.d_run_x;
02082   // m_torque_d[1] = i_stp.d_run_y;
02083   // std::cerr << "[" << m_profile.instance_name << "]  RUNST" << std::endl;
02084   // std::cerr << "[" << m_profile.instance_name << "]   m_torque_k  = [" << m_torque_k[0] << ", " <<  m_torque_k[1] << "]" << std::endl;
02085   // std::cerr << "[" << m_profile.instance_name << "]   m_torque_d  = [" << m_torque_d[0] << ", " <<  m_torque_d[1] << "]" << std::endl;
02086   // std::cerr << "[" << m_profile.instance_name << "]   k_run_b  = [" << k_run_b[0] << ", " <<  k_run_b[1] << "]" << std::endl;
02087   // std::cerr << "[" << m_profile.instance_name << "]   d_run_b  = [" << d_run_b[0] << ", " <<  d_run_b[1] << "]" << std::endl;
02088   std::cerr << "[" << m_profile.instance_name << "]  EEFM" << std::endl;
02089   for (size_t i = 0; i < 2; i++) {
02090     eefm_k1[i] = i_stp.eefm_k1[i];
02091     eefm_k2[i] = i_stp.eefm_k2[i];
02092     eefm_k3[i] = i_stp.eefm_k3[i];
02093     eefm_zmp_delay_time_const[i] = i_stp.eefm_zmp_delay_time_const[i];
02094     ref_zmp_aux(i) = i_stp.eefm_ref_zmp_aux[i];
02095     eefm_body_attitude_control_gain[i] = i_stp.eefm_body_attitude_control_gain[i];
02096     eefm_body_attitude_control_time_const[i] = i_stp.eefm_body_attitude_control_time_const[i];
02097     ref_cp(i) = i_stp.ref_capture_point[i];
02098     act_cp(i) = i_stp.act_capture_point[i];
02099     cp_offset(i) = i_stp.cp_offset[i];
02100   }
02101   bool is_damping_parameter_ok = true;
02102   if ( i_stp.eefm_pos_damping_gain.length () == stikp.size() &&
02103        i_stp.eefm_pos_time_const_support.length () == stikp.size() &&
02104        i_stp.eefm_pos_compensation_limit.length () == stikp.size() &&
02105        i_stp.eefm_swing_pos_spring_gain.length () == stikp.size() &&
02106        i_stp.eefm_swing_pos_time_const.length () == stikp.size() &&
02107        i_stp.eefm_rot_damping_gain.length () == stikp.size() &&
02108        i_stp.eefm_rot_time_const.length () == stikp.size() &&
02109        i_stp.eefm_rot_compensation_limit.length () == stikp.size() &&
02110        i_stp.eefm_swing_rot_spring_gain.length () == stikp.size() &&
02111        i_stp.eefm_swing_rot_time_const.length () == stikp.size() &&
02112        i_stp.eefm_ee_moment_limit.length () == stikp.size() &&
02113        i_stp.eefm_ee_forcemoment_distribution_weight.length () == stikp.size()) {
02114       is_damping_parameter_ok = true;
02115       for (size_t j = 0; j < stikp.size(); j++) {
02116           for (size_t i = 0; i < 3; i++) {
02117               stikp[j].eefm_pos_damping_gain(i) = i_stp.eefm_pos_damping_gain[j][i];
02118               stikp[j].eefm_pos_time_const_support(i) = i_stp.eefm_pos_time_const_support[j][i];
02119               stikp[j].eefm_swing_pos_spring_gain(i) = i_stp.eefm_swing_pos_spring_gain[j][i];
02120               stikp[j].eefm_swing_pos_time_const(i) = i_stp.eefm_swing_pos_time_const[j][i];
02121               stikp[j].eefm_rot_damping_gain(i) = i_stp.eefm_rot_damping_gain[j][i];
02122               stikp[j].eefm_rot_time_const(i) = i_stp.eefm_rot_time_const[j][i];
02123               stikp[j].eefm_swing_rot_spring_gain(i) = i_stp.eefm_swing_rot_spring_gain[j][i];
02124               stikp[j].eefm_swing_rot_time_const(i) = i_stp.eefm_swing_rot_time_const[j][i];
02125               stikp[j].eefm_ee_moment_limit(i) = i_stp.eefm_ee_moment_limit[j][i];
02126               stikp[j].eefm_ee_forcemoment_distribution_weight(i) = i_stp.eefm_ee_forcemoment_distribution_weight[j][i];
02127               stikp[j].eefm_ee_forcemoment_distribution_weight(i+3) = i_stp.eefm_ee_forcemoment_distribution_weight[j][i+3];
02128           }
02129           stikp[j].eefm_pos_compensation_limit = i_stp.eefm_pos_compensation_limit[j];
02130           stikp[j].eefm_rot_compensation_limit = i_stp.eefm_rot_compensation_limit[j];
02131       }
02132   } else {
02133       is_damping_parameter_ok = false;
02134   }
02135   for (size_t i = 0; i < 3; i++) {
02136     eefm_swing_pos_damping_gain(i) = i_stp.eefm_swing_pos_damping_gain[i];
02137     eefm_swing_rot_damping_gain(i) = i_stp.eefm_swing_rot_damping_gain[i];
02138   }
02139   eefm_pos_time_const_swing = i_stp.eefm_pos_time_const_swing;
02140   eefm_pos_transition_time = i_stp.eefm_pos_transition_time;
02141   eefm_pos_margin_time = i_stp.eefm_pos_margin_time;
02142   szd->set_leg_inside_margin(i_stp.eefm_leg_inside_margin);
02143   szd->set_leg_outside_margin(i_stp.eefm_leg_outside_margin);
02144   szd->set_leg_front_margin(i_stp.eefm_leg_front_margin);
02145   szd->set_leg_rear_margin(i_stp.eefm_leg_rear_margin);
02146   szd->set_vertices_from_margin_params();
02147 
02148   if (i_stp.eefm_support_polygon_vertices_sequence.length() != stikp.size()) {
02149       std::cerr << "[" << m_profile.instance_name << "]   eefm_support_polygon_vertices_sequence cannot be set. Length " << i_stp.eefm_support_polygon_vertices_sequence.length() << " != " << stikp.size() << std::endl;
02150   } else {
02151       std::cerr << "[" << m_profile.instance_name << "]   eefm_support_polygon_vertices_sequence set" << std::endl;
02152       std::vector<std::vector<Eigen::Vector2d> > support_polygon_vec;
02153       for (size_t ee_idx = 0; ee_idx < i_stp.eefm_support_polygon_vertices_sequence.length(); ee_idx++) {
02154           std::vector<Eigen::Vector2d> tvec;
02155           for (size_t v_idx = 0; v_idx < i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices.length(); v_idx++) {
02156               tvec.push_back(Eigen::Vector2d(i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices[v_idx].pos[0],
02157                                              i_stp.eefm_support_polygon_vertices_sequence[ee_idx].vertices[v_idx].pos[1]));
02158           }
02159           support_polygon_vec.push_back(tvec);
02160       }
02161       szd->set_vertices(support_polygon_vec);
02162       szd->print_vertices(std::string(m_profile.instance_name));
02163   }
02164   eefm_use_force_difference_control = i_stp.eefm_use_force_difference_control;
02165   eefm_use_swing_damping = i_stp.eefm_use_swing_damping;
02166   for (size_t i = 0; i < 3; ++i) {
02167       eefm_swing_damping_force_thre[i] = i_stp.eefm_swing_damping_force_thre[i];
02168       eefm_swing_damping_moment_thre[i] = i_stp.eefm_swing_damping_moment_thre[i];
02169   }
02170   act_cogvel_filter->setCutOffFreq(i_stp.eefm_cogvel_cutoff_freq);
02171   szd->set_wrench_alpha_blending(i_stp.eefm_wrench_alpha_blending);
02172   szd->set_alpha_cutoff_freq(i_stp.eefm_alpha_cutoff_freq);
02173   eefm_gravitational_acceleration = i_stp.eefm_gravitational_acceleration;
02174   for (size_t i = 0; i < stikp.size(); i++) {
02175       stikp[i].target_ee_diff_p_filter->setCutOffFreq(i_stp.eefm_ee_error_cutoff_freq);
02176       stikp[i].target_ee_diff_r_filter->setCutOffFreq(i_stp.eefm_ee_error_cutoff_freq);
02177       stikp[i].limb_length_margin = i_stp.limb_length_margin[i];
02178   }
02179   setBoolSequenceParam(is_ik_enable, i_stp.is_ik_enable, std::string("is_ik_enable"));
02180   setBoolSequenceParamWithCheckContact(is_feedback_control_enable, i_stp.is_feedback_control_enable, std::string("is_feedback_control_enable"));
02181   setBoolSequenceParam(is_zmp_calc_enable, i_stp.is_zmp_calc_enable, std::string("is_zmp_calc_enable"));
02182   emergency_check_mode = i_stp.emergency_check_mode;
02183 
02184   transition_time = i_stp.transition_time;
02185   cop_check_margin = i_stp.cop_check_margin;
02186   for (size_t i = 0; i < cp_check_margin.size(); i++) {
02187     cp_check_margin[i] = i_stp.cp_check_margin[i];
02188   }
02189   szd->set_vertices_from_margin_params(cp_check_margin);
02190   for (size_t i = 0; i < tilt_margin.size(); i++) {
02191     tilt_margin[i] = i_stp.tilt_margin[i];
02192   }
02193   contact_decision_threshold = i_stp.contact_decision_threshold;
02194   is_estop_while_walking = i_stp.is_estop_while_walking;
02195   use_limb_stretch_avoidance = i_stp.use_limb_stretch_avoidance;
02196   use_zmp_truncation = i_stp.use_zmp_truncation;
02197   limb_stretch_avoidance_time_const = i_stp.limb_stretch_avoidance_time_const;
02198   for (size_t i = 0; i < 2; i++) {
02199     limb_stretch_avoidance_vlimit[i] = i_stp.limb_stretch_avoidance_vlimit[i];
02200     root_rot_compensation_limit[i] = i_stp.root_rot_compensation_limit[i];
02201   }
02202   detection_count_to_air = static_cast<int>(i_stp.detection_time_to_air / dt);
02203   if (control_mode == MODE_IDLE) {
02204       for (size_t i = 0; i < i_stp.end_effector_list.length(); i++) {
02205           std::vector<STIKParam>::iterator it = std::find_if(stikp.begin(), stikp.end(), (&boost::lambda::_1->* &std::vector<STIKParam>::value_type::ee_name == std::string(i_stp.end_effector_list[i].leg)));
02206           memcpy(it->localp.data(), i_stp.end_effector_list[i].pos, sizeof(double)*3);
02207           it->localR = (Eigen::Quaternion<double>(i_stp.end_effector_list[i].rot[0], i_stp.end_effector_list[i].rot[1], i_stp.end_effector_list[i].rot[2], i_stp.end_effector_list[i].rot[3])).normalized().toRotationMatrix();
02208       }
02209   } else {
02210       std::cerr << "[" << m_profile.instance_name << "] cannot change end-effectors except during MODE_IDLE" << std::endl;
02211   }
02212   for (std::vector<STIKParam>::const_iterator it = stikp.begin(); it != stikp.end(); it++) {
02213       std::cerr << "[" << m_profile.instance_name << "]  End Effector [" << it->ee_name << "]" << std::endl;
02214       std::cerr << "[" << m_profile.instance_name << "]   localpos = " << it->localp.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[m]" << std::endl;
02215       std::cerr << "[" << m_profile.instance_name << "]   localR = " << it->localR.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", "", "    [", "]")) << std::endl;
02216   }
02217   if (i_stp.foot_origin_offset.length () != 2) {
02218       std::cerr << "[" << m_profile.instance_name << "]   foot_origin_offset cannot be set. Length " << i_stp.foot_origin_offset.length() << " != " << 2 << std::endl;
02219   } else if (control_mode != MODE_IDLE) {
02220       std::cerr << "[" << m_profile.instance_name << "]   foot_origin_offset cannot be set. Current control_mode is " << control_mode << std::endl;
02221   } else {
02222       for (size_t i = 0; i < i_stp.foot_origin_offset.length(); i++) {
02223           foot_origin_offset[i](0) = i_stp.foot_origin_offset[i][0];
02224           foot_origin_offset[i](1) = i_stp.foot_origin_offset[i][1];
02225           foot_origin_offset[i](2) = i_stp.foot_origin_offset[i][2];
02226       }
02227   }
02228   std::cerr << "[" << m_profile.instance_name << "]   foot_origin_offset is ";
02229   for (size_t i = 0; i < 2; i++) {
02230       std::cerr << foot_origin_offset[i].format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]"));
02231   }
02232   std::cerr << "[m]" << std::endl;
02233   std::cerr << "[" << m_profile.instance_name << "]   eefm_k1  = [" << eefm_k1[0] << ", " << eefm_k1[1] << "], eefm_k2  = [" << eefm_k2[0] << ", " << eefm_k2[1] << "], eefm_k3  = [" << eefm_k3[0] << ", " << eefm_k3[1] << "]" << std::endl;
02234   std::cerr << "[" << m_profile.instance_name << "]   eefm_zmp_delay_time_const  = [" << eefm_zmp_delay_time_const[0] << ", " << eefm_zmp_delay_time_const[1] << "][s], eefm_ref_zmp_aux  = [" << ref_zmp_aux(0) << ", " << ref_zmp_aux(1) << "][m]" << std::endl;
02235   std::cerr << "[" << m_profile.instance_name << "]   eefm_body_attitude_control_gain  = [" << eefm_body_attitude_control_gain[0] << ", " << eefm_body_attitude_control_gain[1] << "], eefm_body_attitude_control_time_const  = [" << eefm_body_attitude_control_time_const[0] << ", " << eefm_body_attitude_control_time_const[1] << "][s]" << std::endl;
02236   if (is_damping_parameter_ok) {
02237       for (size_t j = 0; j < stikp.size(); j++) {
02238           std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[j].ee_name << "] eefm_rot_damping_gain = "
02239                     << stikp[j].eefm_rot_damping_gain.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]"))
02240                     << ", eefm_rot_time_const = "
02241                     << stikp[j].eefm_rot_time_const.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]"))
02242                     << "[s]" << std::endl;
02243           std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[j].ee_name << "] eefm_pos_damping_gain = "
02244                     << stikp[j].eefm_pos_damping_gain.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]"))
02245                     << ", eefm_pos_time_const_support = "
02246                     << stikp[j].eefm_pos_time_const_support.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]"))
02247                     << "[s]" << std::endl;
02248           std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[j].ee_name << "] "
02249                     << "eefm_pos_compensation_limit = " << stikp[j].eefm_pos_compensation_limit << "[m], "
02250                     << "eefm_rot_compensation_limit = " << stikp[j].eefm_rot_compensation_limit << "[rad], "
02251                     << "eefm_ee_moment_limit = " << stikp[j].eefm_ee_moment_limit.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "[Nm]" << std::endl;
02252           std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[j].ee_name << "] "
02253                     << "eefm_swing_pos_spring_gain = " << stikp[j].eefm_swing_pos_spring_gain.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << ", "
02254                     << "eefm_swing_pos_time_const = " << stikp[j].eefm_swing_pos_time_const.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << ", "
02255                     << "eefm_swing_rot_spring_gain = " << stikp[j].eefm_swing_rot_spring_gain.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << ", "
02256                     << "eefm_swing_pos_time_const = " << stikp[j].eefm_swing_pos_time_const.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << ", "
02257                     << std::endl;
02258           std::cerr << "[" << m_profile.instance_name << "]   [" << stikp[j].ee_name << "] "
02259                     << "eefm_ee_forcemoment_distribution_weight = " << stikp[j].eefm_ee_forcemoment_distribution_weight.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", "    [", "]")) << "" << std::endl;
02260       }
02261   } else {
02262       std::cerr << "[" << m_profile.instance_name << "]   eefm damping parameters cannot be set because of invalid param." << std::endl;
02263   }
02264   std::cerr << "[" << m_profile.instance_name << "]   eefm_pos_transition_time = " << eefm_pos_transition_time << "[s], eefm_pos_margin_time = " << eefm_pos_margin_time << "[s] eefm_pos_time_const_swing = " << eefm_pos_time_const_swing << "[s]" << std::endl;
02265   std::cerr << "[" << m_profile.instance_name << "]   cogvel_cutoff_freq = " << act_cogvel_filter->getCutOffFreq() << "[Hz]" << std::endl;
02266   szd->print_params(std::string(m_profile.instance_name));
02267   std::cerr << "[" << m_profile.instance_name << "]   eefm_gravitational_acceleration = " << eefm_gravitational_acceleration << "[m/s^2], eefm_use_force_difference_control = " << (eefm_use_force_difference_control? "true":"false") << ", eefm_use_swing_damping = " << (eefm_use_swing_damping? "true":"false") << std::endl;
02268   std::cerr << "[" << m_profile.instance_name << "]   eefm_ee_error_cutoff_freq = " << stikp[0].target_ee_diff_p_filter->getCutOffFreq() << "[Hz]" << std::endl;
02269   std::cerr << "[" << m_profile.instance_name << "]  COMMON" << std::endl;
02270   if (control_mode == MODE_IDLE) {
02271     st_algorithm = i_stp.st_algorithm;
02272     std::cerr << "[" << m_profile.instance_name << "]   st_algorithm changed to [" << getStabilizerAlgorithmString(st_algorithm) << "]" << std::endl;
02273   } else {
02274     std::cerr << "[" << m_profile.instance_name << "]   st_algorithm cannot be changed to [" << getStabilizerAlgorithmString(st_algorithm) << "] during MODE_AIR or MODE_ST." << std::endl;
02275   }
02276   std::cerr << "[" << m_profile.instance_name << "]   emergency_check_mode changed to [" << (emergency_check_mode == OpenHRP::StabilizerService::NO_CHECK?"NO_CHECK": (emergency_check_mode == OpenHRP::StabilizerService::COP?"COP":"CP") ) << "]" << std::endl;
02277   std::cerr << "[" << m_profile.instance_name << "]   transition_time = " << transition_time << "[s]" << std::endl;
02278   std::cerr << "[" << m_profile.instance_name << "]   cop_check_margin = " << cop_check_margin << "[m], "
02279             << "cp_check_margin = [" << cp_check_margin[0] << ", " << cp_check_margin[1] << ", " << cp_check_margin[2] << ", " << cp_check_margin[3] << "] [m], "
02280             << "tilt_margin = [" << tilt_margin[0] << ", " << tilt_margin[1] << "] [rad]" << std::endl;
02281   std::cerr << "[" << m_profile.instance_name << "]   contact_decision_threshold = " << contact_decision_threshold << "[N], detection_time_to_air = " << detection_count_to_air * dt << "[s]" << std::endl;
02282   std::cerr << "[" << m_profile.instance_name << "]   root_rot_compensation_limit = [" << root_rot_compensation_limit[0] << " " << root_rot_compensation_limit[1] << "][rad]" << std::endl;
02283   // IK limb parameters
02284   std::cerr << "[" << m_profile.instance_name << "]  IK limb parameters" << std::endl;
02285   bool is_ik_limb_parameter_valid_length = true;
02286   if (i_stp.ik_limb_parameters.length() != jpe_v.size()) {
02287       is_ik_limb_parameter_valid_length = false;
02288       std::cerr << "[" << m_profile.instance_name << "]   ik_limb_parameters invalid length! Cannot be set. (input = " << i_stp.ik_limb_parameters.length() << ", desired = " << jpe_v.size() << ")" << std::endl;
02289   } else {
02290       for (size_t i = 0; i < jpe_v.size(); i++) {
02291           if (jpe_v[i]->numJoints() != i_stp.ik_limb_parameters[i].ik_optional_weight_vector.length())
02292               is_ik_limb_parameter_valid_length = false;
02293       }
02294       if (is_ik_limb_parameter_valid_length) {
02295           for (size_t i = 0; i < jpe_v.size(); i++) {
02296               const OpenHRP::StabilizerService::IKLimbParameters& ilp = i_stp.ik_limb_parameters[i];
02297               std::vector<double> ov;
02298               ov.resize(jpe_v[i]->numJoints());
02299               for (size_t j = 0; j < jpe_v[i]->numJoints(); j++) {
02300                   ov[j] = ilp.ik_optional_weight_vector[j];
02301               }
02302               jpe_v[i]->setOptionalWeightVector(ov);
02303               jpe_v[i]->setSRGain(ilp.sr_gain);
02304               stikp[i].avoid_gain = ilp.avoid_gain;
02305               stikp[i].reference_gain = ilp.reference_gain;
02306               jpe_v[i]->setManipulabilityLimit(ilp.manipulability_limit);
02307               stikp[i].ik_loop_count = ilp.ik_loop_count; // unsigned short -> size_t, value not change
02308           }
02309       } else {
02310           std::cerr << "[" << m_profile.instance_name << "]   ik_optional_weight_vector invalid length! Cannot be set. (input = [";
02311           for (size_t i = 0; i < jpe_v.size(); i++) {
02312               std::cerr << i_stp.ik_limb_parameters[i].ik_optional_weight_vector.length() << ", ";
02313           }
02314           std::cerr << "], desired = [";
02315           for (size_t i = 0; i < jpe_v.size(); i++) {
02316               std::cerr << jpe_v[i]->numJoints() << ", ";
02317           }
02318           std::cerr << "])" << std::endl;
02319       }
02320   }
02321   if (is_ik_limb_parameter_valid_length) {
02322       std::cerr << "[" << m_profile.instance_name << "]   ik_optional_weight_vectors = ";
02323       for (size_t i = 0; i < jpe_v.size(); i++) {
02324           std::vector<double> ov;
02325           ov.resize(jpe_v[i]->numJoints());
02326           jpe_v[i]->getOptionalWeightVector(ov);
02327           std::cerr << "[";
02328           for (size_t j = 0; j < jpe_v[i]->numJoints(); j++) {
02329               std::cerr << ov[j] << " ";
02330           }
02331           std::cerr << "]";
02332       }
02333       std::cerr << std::endl;
02334       std::cerr << "[" << m_profile.instance_name << "]   sr_gains = [";
02335       for (size_t i = 0; i < jpe_v.size(); i++) {
02336           std::cerr << jpe_v[i]->getSRGain() << ", ";
02337       }
02338       std::cerr << "]" << std::endl;
02339       std::cerr << "[" << m_profile.instance_name << "]   avoid_gains = [";
02340       for (size_t i = 0; i < stikp.size(); i++) {
02341           std::cerr << stikp[i].avoid_gain << ", ";
02342       }
02343       std::cerr << "]" << std::endl;
02344       std::cerr << "[" << m_profile.instance_name << "]   reference_gains = [";
02345       for (size_t i = 0; i < stikp.size(); i++) {
02346           std::cerr << stikp[i].reference_gain << ", ";
02347       }
02348       std::cerr << "]" << std::endl;
02349       std::cerr << "[" << m_profile.instance_name << "]   manipulability_limits = [";
02350       for (size_t i = 0; i < jpe_v.size(); i++) {
02351           std::cerr << jpe_v[i]->getManipulabilityLimit() << ", ";
02352       }
02353       std::cerr << "]" << std::endl;
02354       std::cerr << "[" << m_profile.instance_name << "]   ik_loop_count = [";
02355       for (size_t i = 0; i < stikp.size(); i++) {
02356           std::cerr << stikp[i].ik_loop_count << ", ";
02357       }
02358       std::cerr << "]" << std::endl;
02359   }
02360 }
02361 
02362 std::string Stabilizer::getStabilizerAlgorithmString (OpenHRP::StabilizerService::STAlgorithm _st_algorithm)
02363 {
02364     switch (_st_algorithm) {
02365     case OpenHRP::StabilizerService::TPCC:
02366         return "TPCC";
02367     case OpenHRP::StabilizerService::EEFM:
02368         return "EEFM";
02369     case OpenHRP::StabilizerService::EEFMQP:
02370         return "EEFMQP";
02371     case OpenHRP::StabilizerService::EEFMQPCOP:
02372         return "EEFMQPCOP";
02373     case OpenHRP::StabilizerService::EEFMQPCOP2:
02374         return "EEFMQPCOP2";
02375     default:
02376         return "";
02377     }
02378 };
02379 
02380 void Stabilizer::setBoolSequenceParam (std::vector<bool>& st_bool_values, const OpenHRP::StabilizerService::BoolSequence& output_bool_values, const std::string& prop_name)
02381 {
02382   std::vector<bool> prev_values;
02383   prev_values.resize(st_bool_values.size());
02384   copy (st_bool_values.begin(), st_bool_values.end(), prev_values.begin());
02385   if (st_bool_values.size() != output_bool_values.length()) {
02386       std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " cannot be set. Length " << st_bool_values.size() << " != " << output_bool_values.length() << std::endl;
02387   } else if ( (control_mode != MODE_IDLE) ) {
02388       std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " cannot be set. Current control_mode is " << control_mode << std::endl;
02389   } else {
02390       for (size_t i = 0; i < st_bool_values.size(); i++) {
02391           st_bool_values[i] = output_bool_values[i];
02392       }
02393   }
02394   std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " is ";
02395   for (size_t i = 0; i < st_bool_values.size(); i++) {
02396       std::cerr <<"[" << st_bool_values[i] << "]";
02397   }
02398   std::cerr << "(set = ";
02399   for (size_t i = 0; i < output_bool_values.length(); i++) {
02400       std::cerr <<"[" << output_bool_values[i] << "]";
02401   }
02402   std::cerr << ", prev = ";
02403   for (size_t i = 0; i < prev_values.size(); i++) {
02404       std::cerr <<"[" << prev_values[i] << "]";
02405   }
02406   std::cerr << ")" << std::endl;
02407 };
02408 
02409 void Stabilizer::setBoolSequenceParamWithCheckContact (std::vector<bool>& st_bool_values, const OpenHRP::StabilizerService::BoolSequence& output_bool_values, const std::string& prop_name)
02410 {
02411   std::vector<bool> prev_values;
02412   prev_values.resize(st_bool_values.size());
02413   copy (st_bool_values.begin(), st_bool_values.end(), prev_values.begin());
02414   if (st_bool_values.size() != output_bool_values.length()) {
02415       std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " cannot be set. Length " << st_bool_values.size() << " != " << output_bool_values.length() << std::endl;
02416   } else if ( control_mode == MODE_IDLE ) {
02417     for (size_t i = 0; i < st_bool_values.size(); i++) {
02418       st_bool_values[i] = output_bool_values[i];
02419     }
02420   } else {
02421     std::vector<size_t> failed_indices;
02422     for (size_t i = 0; i < st_bool_values.size(); i++) {
02423       if ( (st_bool_values[i] != output_bool_values[i]) ) { // If mode change
02424         if (!ref_contact_states[i] ) { // reference contact_states should be OFF
02425           st_bool_values[i] = output_bool_values[i];
02426         } else {
02427           failed_indices.push_back(i);
02428         }
02429       }
02430     }
02431     if (failed_indices.size() > 0) {
02432       std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " cannot be set partially. failed_indices is [";
02433       for (size_t i = 0; i < failed_indices.size(); i++) {
02434         std::cerr << failed_indices[i] << " ";
02435       }
02436       std::cerr << "]" << std::endl;
02437     }
02438   }
02439   std::cerr << "[" << m_profile.instance_name << "]   " << prop_name << " is ";
02440   for (size_t i = 0; i < st_bool_values.size(); i++) {
02441       std::cerr <<"[" << st_bool_values[i] << "]";
02442   }
02443   std::cerr << "(set = ";
02444   for (size_t i = 0; i < output_bool_values.length(); i++) {
02445       std::cerr <<"[" << output_bool_values[i] << "]";
02446   }
02447   std::cerr << ", prev = ";
02448   for (size_t i = 0; i < prev_values.size(); i++) {
02449       std::cerr <<"[" << prev_values[i] << "]";
02450   }
02451   std::cerr << ")" << std::endl;
02452 };
02453 
02454 void Stabilizer::waitSTTransition()
02455 {
02456   // Wait condition
02457   //   1. Check transition_count : Wait until transition is finished
02458   //   2. Check control_mode : Once control_mode is SYNC mode, wait until control_mode moves to the next mode (MODE_AIR or MODE_IDLE)
02459   bool flag = (control_mode == MODE_SYNC_TO_AIR || control_mode == MODE_SYNC_TO_IDLE);
02460   while (transition_count != 0 ||
02461          (flag ? !(control_mode == MODE_IDLE || control_mode == MODE_AIR) : false) ) {
02462       usleep(10);
02463       flag = (control_mode == MODE_SYNC_TO_AIR || control_mode == MODE_SYNC_TO_IDLE);
02464   }
02465   usleep(10);
02466 }
02467 
02468 double Stabilizer::vlimit(double value, double llimit_value, double ulimit_value)
02469 {
02470   if (value > ulimit_value) {
02471     return ulimit_value;
02472   } else if (value < llimit_value) {
02473     return llimit_value;
02474   }
02475   return value;
02476 }
02477 
02478 hrp::Vector3 Stabilizer::vlimit(const hrp::Vector3& value, double llimit_value, double ulimit_value)
02479 {
02480   hrp::Vector3 ret;
02481   for (size_t i = 0; i < 3; i++) {
02482       if (value(i) > ulimit_value) {
02483           ret(i) = ulimit_value;
02484       } else if (value(i) < llimit_value) {
02485           ret(i) = llimit_value;
02486       } else {
02487           ret(i) = value(i);
02488       }
02489   }
02490   return ret;
02491 }
02492 
02493 hrp::Vector3 Stabilizer::vlimit(const hrp::Vector3& value, const hrp::Vector3& limit_value)
02494 {
02495   hrp::Vector3 ret;
02496   for (size_t i = 0; i < 3; i++) {
02497       if (value(i) > limit_value(i)) {
02498           ret(i) = limit_value(i);
02499       } else if (value(i) < -1 * limit_value(i)) {
02500           ret(i) = -1 * limit_value(i);
02501       } else {
02502           ret(i) = value(i);
02503       }
02504   }
02505   return ret;
02506 }
02507 
02508 hrp::Vector3 Stabilizer::vlimit(const hrp::Vector3& value, const hrp::Vector3& llimit_value, const hrp::Vector3& ulimit_value)
02509 {
02510   hrp::Vector3 ret;
02511   for (size_t i = 0; i < 3; i++) {
02512       if (value(i) > ulimit_value(i)) {
02513           ret(i) = ulimit_value(i);
02514       } else if (value(i) < llimit_value(i)) {
02515           ret(i) = llimit_value(i);
02516       } else {
02517           ret(i) = value(i);
02518       }
02519   }
02520   return ret;
02521 }
02522 
02523 static double switching_inpact_absorber(double force, double lower_th, double upper_th)
02524 {
02525   double gradient, intercept;
02526   if (force < lower_th) {
02527     return 0;
02528   } else if (force > upper_th) {
02529     return 1;
02530   } else {
02531     gradient = 1.0 / (upper_th - lower_th);
02532     intercept = -lower_th * gradient;
02533     return gradient * force + intercept;
02534   }
02535 }
02536 
02537 void Stabilizer::calcRUNST() {
02538   if ( m_robot->numJoints() == m_qRef.data.length() ) {
02539     std::vector<std::string> target_name;
02540     target_name.push_back("L_ANKLE_R");
02541     target_name.push_back("R_ANKLE_R");
02542 
02543     double angvelx_ref;// = (m_rpyRef.data.r - pangx_ref)/dt;
02544     double angvely_ref;// = (m_rpyRef.data.p - pangy_ref)/dt;
02545     //pangx_ref = m_rpyRef.data.r;
02546     //pangy_ref = m_rpyRef.data.p;
02547     double angvelx = (m_rpy.data.r - pangx)/dt;
02548     double angvely = (m_rpy.data.r - pangy)/dt;
02549     pangx = m_rpy.data.r;
02550     pangy = m_rpy.data.p;
02551 
02552     // update internal robot model
02553     for ( int i = 0; i < m_robot->numJoints(); i++ ){
02554       qorg[i] = m_robot->joint(i)->q;
02555       m_robot->joint(i)->q = m_qRef.data[i];
02556       qrefv[i] = m_qRef.data[i];
02557     }
02558     //double orgjq = m_robot->link("L_FOOT")->joint->q;
02559     double orgjq = m_robot->joint(m_robot->link("L_ANKLE_P")->jointId)->q;
02560     //set root
02561     m_robot->rootLink()->p = hrp::Vector3(0,0,0);
02562     //m_robot->rootLink()->R = hrp::rotFromRpy(m_rpyRef.data.r,m_rpyRef.data.p,m_rpyRef.data.y);
02563     m_robot->calcForwardKinematics();
02564     hrp::Vector3 target_root_p = m_robot->rootLink()->p;
02565     hrp::Matrix33 target_root_R = m_robot->rootLink()->R;
02566     hrp::Vector3 target_foot_p[2];
02567     hrp::Matrix33 target_foot_R[2];
02568     for (size_t i = 0; i < 2; i++) {
02569       target_foot_p[i] = m_robot->link(target_name[i])->p;
02570       target_foot_R[i] = m_robot->link(target_name[i])->R;
02571     }
02572     hrp::Vector3 target_fm = (m_robot->link(target_name[0])->p + m_robot->link(target_name[1])->p)/2;
02573     //hrp::Vector3 org_cm = m_robot->rootLink()->R.transpose() * (m_robot->calcCM() - m_robot->rootLink()->p);
02574     hrp::Vector3 org_cm = m_robot->rootLink()->R.transpose() * (target_fm - m_robot->rootLink()->p);
02575 
02576     // stabilizer loop
02577     if ( ( m_wrenches[1].data.length() > 0 && m_wrenches[0].data.length() > 0 )
02578          //( m_wrenches[ST_LEFT].data[2] > m_robot->totalMass()/4 || m_wrenches[ST_RIGHT].data[2] > m_robot->totalMass()/4 )
02579          ) {
02580 
02581       for ( int i = 0; i < m_robot->numJoints(); i++ ) {
02582         m_robot->joint(i)->q = qorg[i];
02583       }
02584       // set root
02585       double rddx;// = k_run_b[0] * (m_rpyRef.data.r - m_rpy.data.r) + d_run_b[0] * (angvelx_ref - angvelx);
02586       double rddy;// = k_run_b[1] * (m_rpyRef.data.p - m_rpy.data.p) + d_run_b[1] * (angvely_ref - angvely);
02587       rdx += rddx * dt;
02588       rx += rdx * dt;
02589       rdy += rddy * dt;
02590       ry += rdy * dt;
02591       //rx += rddx * dt;
02592       //ry += rddy * dt;
02593       // if (DEBUGP2) {
02594       //   std::cerr << "REFRPY " <<  m_rpyRef.data.r << " " << m_rpyRef.data.p << std::endl;
02595       // }
02596       // if (DEBUGP2) {
02597       //   std::cerr << "RPY " <<  m_rpy.data.r << " " << m_rpy.data.p << std::endl;
02598       //   std::cerr << " rx " << rx << " " << rdx << " " << rddx << std::endl;
02599       //   std::cerr << " ry " << ry << " " << rdy << " " << rddy << std::endl;
02600       // }
02601       hrp::Vector3 root_p_s;
02602       hrp::Matrix33 root_R_s;
02603       rats::rotm3times(root_R_s, hrp::rotFromRpy(rx, ry, 0), target_root_R);
02604       if (DEBUGP2) {
02605         hrp::Vector3 tmp = hrp::rpyFromRot(root_R_s);
02606         std::cerr << "RPY2 " <<  tmp(0) << " " << tmp(1) << std::endl;
02607       }
02608       root_p_s = target_root_p + target_root_R * org_cm - root_R_s * org_cm;
02609       //m_robot->calcForwardKinematics();
02610       // FK
02611       m_robot->rootLink()->R = root_R_s;
02612       m_robot->rootLink()->p = root_p_s;
02613       if (DEBUGP2) {
02614         std::cerr << " rp " << root_p_s[0] << " " << root_p_s[1] << " " << root_p_s[2] << std::endl;
02615       }
02616       m_robot->calcForwardKinematics();
02617       //
02618       hrp::Vector3 current_fm = (m_robot->link(target_name[0])->p + m_robot->link(target_name[1])->p)/2;
02619 
02620       // 3D-LIP model contorller
02621       hrp::Vector3 dr = target_fm - current_fm;
02622       //hrp::Vector3 dr = current_fm - target_fm ;
02623       hrp::Vector3 dr_vel = (dr - pdr)/dt;
02624       pdr = dr;
02625       double tau_y = - m_torque_k[0] * dr(0) - m_torque_d[0] * dr_vel(0);
02626       double tau_x = m_torque_k[1] * dr(1) + m_torque_d[1] * dr_vel(1);
02627       if (DEBUGP2) {
02628         dr*=1e3;
02629         dr_vel*=1e3;
02630         std::cerr << "dr " << dr(0) << " " << dr(1) << " " << dr_vel(0) << " " << dr_vel(1) << std::endl;
02631         std::cerr << "tau_x " << tau_x << std::endl;
02632         std::cerr << "tau_y " << tau_y << std::endl;
02633       }
02634 
02635       double gamma = 0.5; // temp
02636       double tau_xl[2];
02637       double tau_yl[2];
02638       double xfront = 0.125;
02639       double xrear = 0.1;
02640       double yin = 0.02;
02641       double yout = 0.15;
02642       double mg = m_robot->totalMass() * 9.8 * 0.9;// margin
02643       double tq_y_ulimit = mg * xrear;
02644       double tq_y_llimit = -1 * mg * xfront;
02645       double tq_x_ulimit = mg * yout;
02646       double tq_x_llimit = mg * yin;
02647       // left
02648       tau_xl[0] = gamma * tau_x;
02649       tau_yl[0] = gamma * tau_y;
02650       tau_xl[0] = vlimit(tau_xl[0], tq_x_llimit, tq_x_ulimit);
02651       tau_yl[0] = vlimit(tau_yl[0], tq_y_llimit, tq_y_ulimit);
02652       // right
02653       tau_xl[1]= (1- gamma) * tau_x;
02654       tau_yl[1]= (1- gamma) * tau_y;
02655       tau_xl[1] = vlimit(tau_xl[1], -1*tq_x_ulimit, -1*tq_x_llimit);
02656       tau_yl[1] = vlimit(tau_yl[1], tq_y_llimit, tq_y_ulimit);
02657 
02658       double dleg_x[2];
02659       double dleg_y[2];
02660       double tau_y_total = (m_wrenches[1].data[4] + m_wrenches[0].data[4]) / 2;
02661       double dpz;
02662       if (DEBUGP2) {
02663         std::cerr << "tq limit " << tq_x_ulimit << " " << tq_x_llimit << " " << tq_y_ulimit << " " << tq_y_llimit << std::endl;
02664       }
02665       for (size_t i = 0; i < 2; i++) {
02666         // dleg_x[i] = m_tau_x[i].update(m_wrenches[i].data[3], tau_xl[i]);
02667         // dleg_y[i] = m_tau_y[i].update(m_wrenches[i].data[4], tau_yl[i]);
02668         //dleg_x[i] = m_tau_x[i].update(m_wrenches[i].data[3], tau_xl[i]);
02669         dleg_x[i] = m_tau_x[i].update(0,0);
02670         dleg_y[i] = m_tau_y[i].update(tau_y_total, tau_yl[i]);
02671         if (DEBUGP2) {
02672           std::cerr << i << " dleg_x " << dleg_x[i] << std::endl;
02673           std::cerr << i << " dleg_y " << dleg_y[i] << std::endl;
02674           std::cerr << i << " t_x " << m_wrenches[i].data[3] << " "<< tau_xl[i] << std::endl;
02675           std::cerr << i << " t_y " << m_wrenches[i].data[4] << " "<< tau_yl[i] << std::endl;
02676         }
02677       }
02678 
02679       // calc leg rot
02680       hrp::Matrix33 target_R[2];
02681       hrp::Vector3 target_p[2];
02682       for (size_t i = 0; i < 2; i++) {
02683         //rats::rotm3times(target_R[i], hrp::rotFromRpy(dleg_x[i], dleg_y[i], 0), target_foot_R[i]);
02684         rats::rotm3times(target_R[i], hrp::rotFromRpy(0, dleg_y[i], 0), target_foot_R[i]);
02685         //target_p[i] = target_foot_p[i] + target_foot_R[i] * org_cm - target_R[i] * org_cm;
02686         //target_p[i] = target_foot_p[i] + target_foot_R[i] * org_cm - target_R[i] * org_cm;
02687         target_p[i] = target_foot_p[i];
02688       }
02689       // 1=>left, 2=>right
02690       double refdfz = 0;
02691       dpz = m_f_z.update((m_wrenches[0].data[2] - m_wrenches[1].data[2]), refdfz);
02692       //target_p[0](2) = target_foot_p[0](2) + dpz/2;
02693       //target_p[1](2) = target_foot_p[1](2) - dpz/2;
02694       target_p[0](2) = target_foot_p[0](2);
02695       target_p[1](2) = target_foot_p[1](2);
02696 
02697       // IK
02698       for (size_t i = 0; i < 2; i++) {
02699         hrp::Link* target = m_robot->link(target_name[i]);
02700         hrp::Vector3 vel_p, vel_r;
02701         vel_p = target_p[i] - target->p;
02702         rats::difference_rotation(vel_r, target->R, target_R[i]);
02703         //jpe_v[i]->solveLimbIK(vel_p, vel_r, transition_count, 0.001, 0.01, MAX_TRANSITION_COUNT, qrefv, DEBUGP);
02704         //jpe_v[i]->solveLimbIK(vel_p, vel_r, transition_count, 0.001, 0.01, MAX_TRANSITION_COUNT, qrefv, false);
02705         //m_robot->joint(m_robot->link(target_name[i])->jointId)->q = dleg_y[i] + orgjq;
02706       }
02707       // m_robot->joint(m_robot->link("L_ANKLE_P")->jointId)->q = transition_smooth_gain * dleg_y[0] + orgjq + m_rpy.data.p;
02708       // m_robot->joint(m_robot->link("R_ANKLE_P")->jointId)->q = transition_smooth_gain * dleg_y[1] + orgjq + m_rpy.data.p;
02709       m_robot->joint(m_robot->link("L_ANKLE_P")->jointId)->q = transition_smooth_gain * dleg_y[0] + orgjq;
02710       m_robot->joint(m_robot->link("R_ANKLE_P")->jointId)->q = transition_smooth_gain * dleg_y[1] + orgjq;
02711     } else {
02712       // reinitialize
02713       for (int i = 0; i < 2; i++) {
02714         m_tau_x[i].reset();
02715         m_tau_y[i].reset();
02716         m_f_z.reset();
02717       }
02718     }
02719   }
02720 }
02721 
02722 void Stabilizer::calcContactMatrix (hrp::dmatrix& tm, const std::vector<hrp::Vector3>& contact_p)
02723 {
02724   // tm.resize(6,6*contact_p.size());
02725   // tm.setZero();
02726   // for (size_t c = 0; c < contact_p.size(); c++) {
02727   //   for (size_t i = 0; i < 6; i++) tm(i,(c*6)+i) = 1.0;
02728   //   hrp::Matrix33 cm;
02729   //   rats::outer_product_matrix(cm, contact_p[c]);
02730   //   for (size_t i = 0; i < 3; i++)
02731   //     for (size_t j = 0; j < 3; j++) tm(i+3,(c*6)+j) = cm(i,j);
02732   // }
02733 }
02734 
02735 void Stabilizer::calcTorque ()
02736 {
02737   m_robot->calcForwardKinematics();
02738   // buffers for the unit vector method
02739   hrp::Vector3 root_w_x_v;
02740   hrp::Vector3 g(0, 0, 9.80665);
02741   root_w_x_v = m_robot->rootLink()->w.cross(m_robot->rootLink()->vo + m_robot->rootLink()->w.cross(m_robot->rootLink()->p));
02742   m_robot->rootLink()->dvo = g - root_w_x_v;   // dv = g, dw = 0
02743   m_robot->rootLink()->dw.setZero();
02744 
02745   hrp::Vector3 root_f;
02746   hrp::Vector3 root_t;
02747   m_robot->calcInverseDynamics(m_robot->rootLink(), root_f, root_t);
02748   // if (loop % 200 == 0) {
02749   //   std::cerr << ":mass " << m_robot->totalMass() << std::endl;
02750   //   std::cerr << ":cog "; rats::print_vector(std::cerr, m_robot->calcCM());
02751   //   for(int i = 0; i < m_robot->numJoints(); ++i){
02752   //     std::cerr << "(list :" << m_robot->link(i)->name << " "
02753   //               << m_robot->joint(i)->jointId << " "
02754   //               << m_robot->link(i)->m << " ";
02755   //     hrp::Vector3 tmpc = m_robot->link(i)->p + m_robot->link(i)->R * m_robot->link(i)->c;
02756   //     rats::print_vector(std::cerr, tmpc, false);
02757   //     std::cerr << " ";
02758   //     rats::print_vector(std::cerr, m_robot->link(i)->c, false);
02759   //     std::cerr << ")" << std::endl;
02760   //   }
02761   // }
02762   // if (loop % 200 == 0) {
02763   //   std::cerr << ":IV1 (list ";
02764   //   for(int i = 0; i < m_robot->numJoints(); ++i){
02765   //     std::cerr << "(list :" << m_robot->joint(i)->name << " " <<  m_robot->joint(i)->u << ")";
02766   //   }
02767   //   std::cerr << ")" << std::endl;
02768   // }
02769   hrp::dmatrix contact_mat, contact_mat_inv;
02770   std::vector<hrp::Vector3> contact_p;
02771   for (size_t j = 0; j < 2; j++) contact_p.push_back(m_robot->sensor<hrp::ForceSensor>(stikp[j].sensor_name)->link->p);
02772   calcContactMatrix(contact_mat, contact_p);
02773   hrp::calcSRInverse(contact_mat, contact_mat_inv, 0.0);
02774   hrp::dvector root_ft(6);
02775   for (size_t j = 0; j < 3; j++) root_ft(j) = root_f(j);
02776   for (size_t j = 0; j < 3; j++) root_ft(j+3) = root_t(j);
02777   hrp::dvector contact_ft(2*6);
02778   contact_ft = contact_mat_inv * root_ft;
02779   // if (loop%200==0) {
02780   //   std::cerr << ":mass " << m_robot->totalMass() << std::endl;
02781   //   // std::cerr << ":ftv "; rats::print_vector(std::cerr, ftv);
02782   //   // std::cerr << ":aa "; rats::print_matrix(std::cerr, aa);
02783   //   // std::cerr << ":dv "; rats::print_vector(std::cerr, dv);
02784   // }
02785   for (size_t j = 0; j < 2; j++) {
02786     hrp::JointPathEx jm = hrp::JointPathEx(m_robot, m_robot->rootLink(), m_robot->sensor<hrp::ForceSensor>(stikp[j].sensor_name)->link, dt);
02787     hrp::dmatrix JJ;
02788     jm.calcJacobian(JJ);
02789     hrp::dvector ft(6);
02790     for (size_t i = 0; i < 6; i++) ft(i) = contact_ft(i+j*6);
02791     hrp::dvector tq_from_extft(jm.numJoints());
02792     tq_from_extft = JJ.transpose() * ft;
02793     // if (loop%200==0) {
02794     //   std::cerr << ":ft "; rats::print_vector(std::cerr, ft);
02795     //   std::cerr << ":JJ "; rats::print_matrix(std::cerr, JJ);
02796     //   std::cerr << ":tq_from_extft "; rats::print_vector(std::cerr, tq_from_extft);
02797     // }
02798     for (size_t i = 0; i < jm.numJoints(); i++) jm.joint(i)->u -= tq_from_extft(i);
02799   }
02800   //hrp::dmatrix MM(6,m_robot->numJoints());
02801   //m_robot->calcMassMatrix(MM);
02802   // if (loop % 200 == 0) {
02803   //   std::cerr << ":INVDYN2 (list "; rats::print_vector(std::cerr, root_f, false);
02804   //   std::cerr << " "; rats::print_vector(std::cerr, root_t, false);
02805   //   std::cerr << ")" << std::endl;
02806   //   // hrp::dvector tqv(m_robot->numJoints());
02807   //   // for(int i = 0; i < m_robot->numJoints(); ++i){p
02808   //   //   tqv[m_robot->joint(i)->jointId] = m_robot->joint(i)->u;
02809   //   // }
02810   //   // std::cerr << ":IV2 "; rats::print_vector(std::cerr, tqv);
02811   //   std::cerr << ":IV2 (list ";
02812   //   for(int i = 0; i < m_robot->numJoints(); ++i){
02813   //     std::cerr << "(list :" << m_robot->joint(i)->name << " " <<  m_robot->joint(i)->u << ")";
02814   //   }
02815   //   std::cerr << ")" << std::endl;
02816   // }
02817 };
02818 
02819 extern "C"
02820 {
02821 
02822   void StabilizerInit(RTC::Manager* manager)
02823   {
02824     RTC::Properties profile(stabilizer_spec);
02825     manager->registerFactory(profile,
02826                              RTC::Create<Stabilizer>,
02827                              RTC::Delete<Stabilizer>);
02828   }
02829 
02830 };
02831 
02832 


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Wed Sep 6 2017 02:35:56