00001
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
00029
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
00043 "conf.default.debugLevel", "0",
00044 ""
00045 };
00046
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
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
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
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
00119
00120 bindParameter("debugLevel", m_debugLevel, "0");
00121
00122
00123
00124
00125
00126
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
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
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
00167 m_StabilizerServicePort.registerProvider("service0", "StabilizerService", m_service0);
00168
00169
00170
00171
00172 addPort(m_StabilizerServicePort);
00173
00174
00175 RTC::Properties& prop = getProperties();
00176 coil::stringTo(dt, prop["dt"].c_str());
00177
00178
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
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
00198 std::vector<std::string> force_sensor_names;
00199
00200
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
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
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
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
00247
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();
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
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()));
00291 ikp.target_ee_diff_r_filter = boost::shared_ptr<FirstOrderLowPassFilter<hrp::Vector3> >(new FirstOrderLowPassFilter<hrp::Vector3>(50.0, dt, hrp::Vector3::Zero()));
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
00298 if (ee_name.find("leg") != std::string::npos && jpe_v.back()->numJoints() == 7) {
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) );
00316 is_feedback_control_enable.push_back( (ee_name.find("leg") != std::string::npos ? true : false) );
00317 is_zmp_calc_enable.push_back( (ee_name.find("leg") != std::string::npos ? true : false) );
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
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
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);
00369 if (ikp.ee_name.find("leg") == std::string::npos) {
00370 ikp.eefm_ee_forcemoment_distribution_weight = Eigen::Matrix<double, 6,1>::Zero();
00371 } else {
00372 for (size_t j = 0; j < 3; j++) {
00373 ikp.eefm_ee_forcemoment_distribution_weight[j] = 1;
00374 ikp.eefm_ee_forcemoment_distribution_weight[j+3] = 1e-2;
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
00393
00394
00395
00396 eefm_gravitational_acceleration = 9.80665;
00397 cop_check_margin = 20.0*1e-3;
00398 cp_check_margin.resize(4, 30*1e-3);
00399 cp_offset = hrp::Vector3(0.0, 0.0, 0.0);
00400 tilt_margin.resize(2, 30 * M_PI / 180);
00401 contact_decision_threshold = 50;
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;
00414 limb_stretch_avoidance_vlimit[1] = 50 * 1e-3 * dt;
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
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
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);
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()));
00472
00473
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);
00482 m_allEEComp.data.length(stikp.size() * 6);
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
00516
00517
00518
00519
00520
00521
00522
00523
00524
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;
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
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
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
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
00692
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
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
00802 hrp::Vector3 foot_origin_pos;
00803 hrp::Matrix33 foot_origin_rot;
00804 if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00805
00806 for ( int i = 0; i < m_robot->numJoints(); i++ ){
00807 m_robot->joint(i)->q = m_qCurrent.data[i];
00808 }
00809
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
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
00829 act_cog = m_robot->calcCM();
00830
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
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
00845
00846
00847 rel_act_zmp = m_robot->rootLink()->R.transpose() * (act_zmp - m_robot->rootLink()->p);
00848 if (st_algorithm != OpenHRP::StabilizerService::TPCC) {
00849
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
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
00862 for (size_t i = 0; i < stikp.size(); i++) {
00863 hrp::Link* target = m_robot->link(stikp[i].target_name);
00864
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
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
00874
00875
00876
00877
00878
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
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);
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
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
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
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
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
00961 if (st_algorithm == OpenHRP::StabilizerService::EEFM) {
00962
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
00992 new_refzmp = foot_origin_rot.transpose() * (new_refzmp - foot_origin_pos);
00993 }
00994
00995
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
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
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
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
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
01017
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
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
01032
01033 {
01034
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) {
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
01049 ikp.ee_d_foot_rpy = ee_R.transpose() * (foot_origin_rot * ikp.d_foot_rpy);
01050
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
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
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
01067
01068
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"]])
01080 || (act_contact_states[0] && act_contact_states[1]) ) {
01081
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"]] ) {
01088 remain_swing_time = m_controlSwingSupportTime.data[contact_states_index_map["rleg"]];
01089 } else {
01090 remain_swing_time = m_controlSwingSupportTime.data[contact_states_index_map["lleg"]];
01091 }
01092
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));
01094
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
01101
01102 pos_ctrl = vlimit(pos_ctrl, -1 * stikp[0].eefm_pos_compensation_limit * 2, stikp[0].eefm_pos_compensation_limit * 2);
01103
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
01120
01121
01122
01123
01124
01125 calcDiffFootOriginExtMoment ();
01126 }
01127 }
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
01155
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;
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
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();
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
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
01211 ref_total_moment += (target_ee_p[i]-ref_zmp).cross(ref_force[i]);
01212
01213
01214
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
01220
01221
01222 if (transition_count == (-1 * calcMaxTransitionCount() + 1)) {
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
01229
01230 new_refzmp = ref_zmp;
01231 rel_cog = m_robot->rootLink()->R.transpose() * (ref_cog-m_robot->rootLink()->p);
01232
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
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
01259 } else {
01260 ref_cogvel = (ref_cog - prev_ref_cog)/dt;
01261 }
01262 prev_ref_cog = ref_cog;
01263
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
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));
01287 nf = eeR.transpose() * nf;
01288 nm = eeR.transpose() * nm;
01289
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);
01297 tmpfz2 += prev_act_force_z[i];
01298 }
01299 if (tmpfz2 < contact_decision_threshold) {
01300 ret_zmp = act_zmp;
01301 return false;
01302 } else {
01303 ret_zmp = hrp::Vector3(tmpzmpx / tmpfz, tmpzmpy / tmpfz, zmp_z);
01304 return true;
01305 }
01306 };
01307
01308 void Stabilizer::calcStateForEmergencySignal()
01309 {
01310
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
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
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 ) {
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
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 ) {
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) {
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
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
01435
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);
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]) {
01464
01465 ikp.support_time = std::min(3600.0, ikp.support_time+dt);
01466
01467
01468
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 {
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
01497
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
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
01518
01519
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
01542
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
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
01567
01568
01569
01570 {
01571
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
01584
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
01593
01594
01595
01596 moveBasePosRotForBodyRPYControl ();
01597
01598
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
01607 calcSwingEEModification();
01608
01609
01610
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
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
01620
01621
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
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
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
01641 stikp[i].localp,
01642 stikp[i].localR);
01643 }
01644 }
01645 }
01646 }
01647
01648
01649
01650
01651
01652 void Stabilizer::calcSwingEEModification ()
01653 {
01654 for (size_t i = 0; i < stikp.size(); i++) {
01655
01656 double limit_pos = 30 * 1e-3;
01657 double limit_rot = deg2rad(10);
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
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
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;
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
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);
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
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;
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
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
01721
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
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
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
01749
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
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
01759 if ( !on_ground ) act_ext_moment = ref_ext_moment;
01760
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
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
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();
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();
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
01877
01878
01879
01880
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
01887
01888
01889
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
02029 memcpy(ret_ee.pos, cur_ee.pos.data(), sizeof(double)*3);
02030
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
02037 ret_ee.leg = stikp.at(i).ee_name.c_str();
02038
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;
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
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
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
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;
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]) ) {
02424 if (!ref_contact_states[i] ) {
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
02457
02458
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;
02544 double angvely_ref;
02545
02546
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
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
02559 double orgjq = m_robot->joint(m_robot->link("L_ANKLE_P")->jointId)->q;
02560
02561 m_robot->rootLink()->p = hrp::Vector3(0,0,0);
02562
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
02574 hrp::Vector3 org_cm = m_robot->rootLink()->R.transpose() * (target_fm - m_robot->rootLink()->p);
02575
02576
02577 if ( ( m_wrenches[1].data.length() > 0 && m_wrenches[0].data.length() > 0 )
02578
02579 ) {
02580
02581 for ( int i = 0; i < m_robot->numJoints(); i++ ) {
02582 m_robot->joint(i)->q = qorg[i];
02583 }
02584
02585 double rddx;
02586 double rddy;
02587 rdx += rddx * dt;
02588 rx += rdx * dt;
02589 rdy += rddy * dt;
02590 ry += rdy * dt;
02591
02592
02593
02594
02595
02596
02597
02598
02599
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
02610
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
02621 hrp::Vector3 dr = target_fm - current_fm;
02622
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;
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;
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
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
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
02667
02668
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
02680 hrp::Matrix33 target_R[2];
02681 hrp::Vector3 target_p[2];
02682 for (size_t i = 0; i < 2; i++) {
02683
02684 rats::rotm3times(target_R[i], hrp::rotFromRpy(0, dleg_y[i], 0), target_foot_R[i]);
02685
02686
02687 target_p[i] = target_foot_p[i];
02688 }
02689
02690 double refdfz = 0;
02691 dpz = m_f_z.update((m_wrenches[0].data[2] - m_wrenches[1].data[2]), refdfz);
02692
02693
02694 target_p[0](2) = target_foot_p[0](2);
02695 target_p[1](2) = target_foot_p[1](2);
02696
02697
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
02704
02705
02706 }
02707
02708
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
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
02725
02726
02727
02728
02729
02730
02731
02732
02733 }
02734
02735 void Stabilizer::calcTorque ()
02736 {
02737 m_robot->calcForwardKinematics();
02738
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;
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
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
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
02780
02781
02782
02783
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
02794
02795
02796
02797
02798 for (size_t i = 0; i < jm.numJoints(); i++) jm.joint(i)->u -= tq_from_extft(i);
02799 }
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
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