00001
00010 #include <rtm/CorbaNaming.h>
00011 #include <hrpModel/Link.h>
00012 #include <hrpModel/Sensor.h>
00013 #include <hrpModel/ModelLoaderUtil.h>
00014 #include <hrpModel/JointPath.h>
00015 #include <hrpUtil/MatrixSolvers.h>
00016 #include "hrpsys/util/Hrpsys.h"
00017 #include <boost/assign.hpp>
00018 #include "ReferenceForceUpdater.h"
00019 #include "hrpsys/util/VectorConvert.h"
00020
00021 typedef coil::Guard<coil::Mutex> Guard;
00022
00023
00024
00025 static const char* ReferenceForceUpdater_spec[] =
00026 {
00027 "implementation_id", "ReferenceForceUpdater",
00028 "type_name", "ReferenceForceUpdater",
00029 "description", "update reference force",
00030 "version", HRPSYS_PACKAGE_VERSION,
00031 "vendor", "AIST",
00032 "category", "example",
00033 "activity_type", "DataFlowComponent",
00034 "max_instance", "10",
00035 "language", "C++",
00036 "lang_type", "compile",
00037
00038 "conf.default.debugLevel", "0",
00039 ""
00040 };
00041
00042
00043 static std::ostream& operator<<(std::ostream& os, const struct RTC::Time &tm)
00044 {
00045 int pre = os.precision();
00046 os.setf(std::ios::fixed);
00047 os << std::setprecision(6)
00048 << (tm.sec + tm.nsec/1e9)
00049 << std::setprecision(pre);
00050 os.unsetf(std::ios::fixed);
00051 return os;
00052 }
00053
00054 ReferenceForceUpdater::ReferenceForceUpdater(RTC::Manager* manager)
00055 : RTC::DataFlowComponentBase(manager),
00056
00057 m_qRefIn("qRef", m_qRef),
00058 m_basePosIn("basePosIn", m_basePos),
00059 m_baseRpyIn("baseRpyIn", m_baseRpy),
00060 m_rpyIn("rpy", m_rpy),
00061 m_diffFootOriginExtMomentIn("diffFootOriginExtMoment", m_diffFootOriginExtMoment),
00062 m_refFootOriginExtMomentOut("refFootOriginExtMoment", m_refFootOriginExtMoment),
00063 m_refFootOriginExtMomentIsHoldValueOut("refFootOriginExtMomentIsHoldValue", m_refFootOriginExtMomentIsHoldValue),
00064 m_ReferenceForceUpdaterServicePort("ReferenceForceUpdaterService"),
00065
00066 m_robot(hrp::BodyPtr()),
00067 m_debugLevel(0),
00068 use_sh_base_pos_rpy(false)
00069 {
00070 m_ReferenceForceUpdaterService.rfu(this);
00071 }
00072
00073 ReferenceForceUpdater::~ReferenceForceUpdater()
00074 {
00075 }
00076
00077
00078
00079 RTC::ReturnCode_t ReferenceForceUpdater::onInitialize()
00080 {
00081 std::cerr << "[" << m_profile.instance_name << "] onInitialize()" << std::endl;
00082
00083
00084 bindParameter("debugLevel", m_debugLevel, "0");
00085
00086
00087
00088
00089
00090
00091 addInPort("qRef", m_qRefIn);
00092 addInPort("basePosIn", m_basePosIn);
00093 addInPort("baseRpyIn",m_baseRpyIn);
00094 addInPort("rpy",m_rpyIn);
00095 addInPort("diffFootOriginExtMoment", m_diffFootOriginExtMomentIn);
00096
00097 addOutPort("refFootOriginExtMoment", m_refFootOriginExtMomentOut);
00098 addOutPort("refFootOriginExtMomentIsHoldValue", m_refFootOriginExtMomentIsHoldValueOut);
00099
00100
00101 m_ReferenceForceUpdaterServicePort.registerProvider("service0", "ReferenceForceUpdaterService", m_ReferenceForceUpdaterService);
00102
00103
00104
00105 addPort(m_ReferenceForceUpdaterServicePort);
00106
00107
00108 RTC::Properties& prop = getProperties();
00109 coil::stringTo(m_dt, prop["dt"].c_str());
00110
00111
00112 m_robot = hrp::BodyPtr(new hrp::Body());
00113 RTC::Manager& rtcManager = RTC::Manager::instance();
00114 std::string nameServer = rtcManager.getConfig()["corba.nameservers"];
00115 int comPos = nameServer.find(",");
00116 if (comPos < 0){
00117 comPos = nameServer.length();
00118 }
00119 nameServer = nameServer.substr(0, comPos);
00120 RTC::CorbaNaming naming(rtcManager.getORB(), nameServer.c_str());
00121 if (!loadBodyFromModelLoader(m_robot, prop["model"].c_str(),
00122 CosNaming::NamingContext::_duplicate(naming.getRootContext())
00123 )){
00124 std::cerr << "[" << m_profile.instance_name << "] failed to load model[" << prop["model"] << "]" << std::endl;
00125 return RTC::RTC_ERROR;
00126 }
00127
00128
00129 std::vector<std::string> fsensor_names;
00130
00131 unsigned int npforce = m_robot->numSensors(hrp::Sensor::FORCE);
00132 for (unsigned int i=0; i<npforce; i++){
00133 fsensor_names.push_back(m_robot->sensor(hrp::Sensor::FORCE, i)->name);
00134 }
00135
00136 readVirtualForceSensorParamFromProperties(m_vfs, m_robot, prop["virtual_force_sensor"], std::string(m_profile.instance_name));
00137 unsigned int nvforce = m_vfs.size();
00138 for (unsigned int i=0; i<nvforce; i++){
00139 for ( std::map<std::string, hrp::VirtualForceSensorParam>::iterator it = m_vfs.begin(); it != m_vfs.end(); it++ ) {
00140 if (it->second.id == (int)i) fsensor_names.push_back(it->first);
00141 }
00142 }
00143
00144
00145 unsigned int nforce = npforce + nvforce;
00146 m_force.resize(nforce);
00147 m_forceIn.resize(nforce);
00148 m_ref_force_in.resize(nforce);
00149 m_ref_force_out.resize(nforce);
00150 m_ref_forceIn.resize(nforce);
00151 m_ref_forceOut.resize(nforce);
00152 std::cerr << "[" << m_profile.instance_name << "] create force sensor ports" << std::endl;
00153 for (unsigned int i=0; i<nforce; i++){
00154
00155 m_forceIn[i] = new InPort<TimedDoubleSeq>(fsensor_names[i].c_str(), m_force[i]);
00156 m_force[i].data.length(6);
00157 registerInPort(fsensor_names[i].c_str(), *m_forceIn[i]);
00158
00159 m_ref_force_in[i].data.length(6);
00160 for (unsigned int j=0; j<6; j++) m_ref_force_in[i].data[j] = 0.0;
00161 m_ref_forceIn[i] = new InPort<TimedDoubleSeq>(std::string("ref_"+fsensor_names[i]+"In").c_str(), m_ref_force_in[i]);
00162 registerInPort(std::string("ref_"+fsensor_names[i]+"In").c_str(), *m_ref_forceIn[i]);
00163 std::cerr << "[" << m_profile.instance_name << "] name = " << fsensor_names[i] << std::endl;
00164
00165 m_ref_force_out[i].data.length(6);
00166 for (unsigned int j=0; j<6; j++) m_ref_force_out[i].data[j] = 0.0;
00167 m_ref_forceOut[i] = new OutPort<TimedDoubleSeq>(std::string("ref_"+fsensor_names[i]+"Out").c_str(), m_ref_force_out[i]);
00168 registerOutPort(std::string("ref_"+fsensor_names[i]+"Out").c_str(), *m_ref_forceOut[i]);
00169 std::cerr << "[" << m_profile.instance_name << "] name = " << fsensor_names[i] << std::endl;
00170 }
00171
00172
00173
00174 coil::vstring end_effectors_str = coil::split(prop["end_effectors"], ",");
00175 if (end_effectors_str.size() > 0) {
00176 size_t prop_num = 10;
00177 size_t num = end_effectors_str.size()/prop_num;
00178 for (size_t i = 0; i < num; i++) {
00179 std::string ee_name, ee_target, ee_base;
00180 coil::stringTo(ee_name, end_effectors_str[i*prop_num].c_str());
00181 coil::stringTo(ee_target, end_effectors_str[i*prop_num+1].c_str());
00182 coil::stringTo(ee_base, end_effectors_str[i*prop_num+2].c_str());
00183 ee_trans eet;
00184 for (size_t j = 0; j < 3; j++) {
00185 coil::stringTo(eet.localPos(j), end_effectors_str[i*prop_num+3+j].c_str());
00186 }
00187 double tmpv[4];
00188 for (int j = 0; j < 4; j++ ) {
00189 coil::stringTo(tmpv[j], end_effectors_str[i*prop_num+6+j].c_str());
00190 }
00191 eet.localR = Eigen::AngleAxis<double>(tmpv[3], hrp::Vector3(tmpv[0], tmpv[1], tmpv[2])).toRotationMatrix();
00192 eet.target_name = ee_target;
00193 {
00194 bool is_ee_exists = false;
00195 for (size_t j = 0; j < nforce; j++) {
00196 hrp::Sensor* sensor = m_robot->sensor(hrp::Sensor::FORCE, j);
00197 hrp::Link* alink = m_robot->link(ee_target);
00198 while (alink != NULL && alink->name != ee_base && !is_ee_exists) {
00199 if ( alink->name == sensor->link->name ) {
00200 is_ee_exists = true;
00201 eet.sensor_name = sensor->name;
00202 }
00203 alink = alink->parent;
00204 }
00205 }
00206 }
00207 ee_map.insert(std::pair<std::string, ee_trans>(ee_name , eet));
00208
00209 ReferenceForceUpdaterParam rfu_param;
00210
00211 rfu_param.update_count = round((1/rfu_param.update_freq)/m_dt);
00212 if (( ee_name != "rleg" ) && ( ee_name != "lleg" ))
00213 m_RFUParam.insert(std::pair<std::string, ReferenceForceUpdaterParam>(ee_name , rfu_param));
00214
00215 ee_index_map.insert(std::pair<std::string, size_t>(ee_name, i));
00216 ref_force.push_back(hrp::Vector3::Zero());
00217
00218 ref_force_interpolator.insert(std::pair<std::string, interpolator*>(ee_name, new interpolator(3, m_dt, interpolator::LINEAR)));
00219 if (( ee_name != "lleg" ) && ( ee_name != "rleg" )) transition_interpolator.insert(std::pair<std::string, interpolator*>(ee_name, new interpolator(1, m_dt)));
00220 std::cerr << "[" << m_profile.instance_name << "] End Effector [" << ee_name << "]" << ee_target << " " << ee_base << std::endl;
00221 std::cerr << "[" << m_profile.instance_name << "] target = " << ee_target << ", base = " << ee_base << ", sensor_name = " << eet.sensor_name << std::endl;
00222 std::cerr << "[" << m_profile.instance_name << "] localPos = " << eet.localPos.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[m]" << std::endl;
00223 std::cerr << "[" << m_profile.instance_name << "] localR = " << eet.localR.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", "\n", " [", "]")) << std::endl;
00224 }
00225
00226 {
00227 std::string ee_name = "footoriginextmoment";
00228 ReferenceForceUpdaterParam rfu_param;
00229 rfu_param.update_count = round((1/rfu_param.update_freq)/m_dt);
00230 m_RFUParam.insert(std::pair<std::string, ReferenceForceUpdaterParam>(ee_name, rfu_param));
00231 ee_trans eet;
00232 eet.localPos = hrp::Vector3::Zero();
00233 eet.localR = hrp::Matrix33::Identity();
00234 eet.target_name = "";
00235 ee_map.insert(std::pair<std::string, ee_trans>(ee_name , eet));
00236 ee_index_map.insert(std::pair<std::string, size_t>(ee_name, ref_force.size()));
00237 ref_force.push_back(hrp::Vector3::Zero());
00238 ref_force_interpolator.insert(std::pair<std::string, interpolator*>(ee_name, new interpolator(3, m_dt, interpolator::LINEAR)));
00239 transition_interpolator.insert(std::pair<std::string, interpolator*>(ee_name, new interpolator(1, m_dt)));
00240 }
00241 }
00242
00243
00244 unsigned int dof = m_robot->numJoints();
00245 for ( unsigned int i = 0 ; i < dof; i++ ){
00246 if ( (int)i != m_robot->joint(i)->jointId ) {
00247 std::cerr << "[" << m_profile.instance_name << "] jointId is not equal to the index number" << std::endl;
00248 return RTC::RTC_ERROR;
00249 }
00250 }
00251
00252 loop = 0;
00253 transition_interpolator_ratio.reserve(transition_interpolator.size());
00254 for (unsigned int i=0; i<transition_interpolator.size(); i++ ) transition_interpolator_ratio[i] = 0;
00255
00256 return RTC::RTC_OK;
00257 }
00258
00259
00260
00261 RTC::ReturnCode_t ReferenceForceUpdater::onFinalize()
00262 {
00263 std::cerr << "[" << m_profile.instance_name << "] onFinalize()" << std::endl;
00264 for ( std::map<std::string, interpolator*>::iterator it = ref_force_interpolator.begin(); it != ref_force_interpolator.end(); it++ ) {
00265 delete it->second;
00266 }
00267 for ( std::map<std::string, interpolator*>::iterator it = transition_interpolator.begin(); it != transition_interpolator.end(); it++ ) {
00268 delete it->second;
00269 }
00270 ref_force_interpolator.clear();
00271 transition_interpolator.clear();
00272 return RTC::RTC_OK;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 RTC::ReturnCode_t ReferenceForceUpdater::onActivated(RTC::UniqueId ec_id)
00290 {
00291 std::cerr << "[" << m_profile.instance_name<< "] onActivated(" << ec_id << ")" << std::endl;
00292 return RTC::RTC_OK;
00293 }
00294
00295 RTC::ReturnCode_t ReferenceForceUpdater::onDeactivated(RTC::UniqueId ec_id)
00296 {
00297 std::cerr << "[" << m_profile.instance_name<< "] onDeactivated(" << ec_id << ")" << std::endl;
00298 return RTC::RTC_OK;
00299 }
00300
00301
00302 #define DEBUGP ((m_debugLevel==1 && loop%200==0) || m_debugLevel > 1 )
00303 RTC::ReturnCode_t ReferenceForceUpdater::onExecute(RTC::UniqueId ec_id)
00304 {
00305 loop ++;
00306
00307
00308 for (unsigned int i=0; i<m_forceIn.size(); i++){
00309 if ( m_forceIn[i]->isNew() ) {
00310 m_forceIn[i]->read();
00311 }
00312 if ( m_ref_forceIn[i]->isNew() ) {
00313 m_ref_forceIn[i]->read();
00314 }
00315 }
00316 if (m_basePosIn.isNew()) {
00317 m_basePosIn.read();
00318 }
00319 if (m_baseRpyIn.isNew()) {
00320 m_baseRpyIn.read();
00321 }
00322 if (m_rpyIn.isNew()) {
00323 m_rpyIn.read();
00324 }
00325 if (m_diffFootOriginExtMomentIn.isNew()) {
00326 m_diffFootOriginExtMomentIn.read();
00327 }
00328 if (m_qRefIn.isNew()) {
00329 m_qRefIn.read();
00330 }
00331
00332
00333 if ( m_qRef.data.length() == m_robot->numJoints() ) {
00334 Guard guard(m_mutex);
00335
00336
00337 for (std::map<std::string, ReferenceForceUpdaterParam>::iterator itr = m_RFUParam.begin(); itr != m_RFUParam.end(); itr++ ) {
00338 std::string arm = itr->first;
00339 size_t arm_idx = ee_index_map[arm];
00340 bool transition_interpolator_isEmpty = transition_interpolator[arm]->isEmpty();
00341 if ( ! transition_interpolator_isEmpty ) {
00342 transition_interpolator[arm]->get(&transition_interpolator_ratio[arm_idx], true);
00343 if ( transition_interpolator[arm]->isEmpty() && m_RFUParam[arm].is_active && m_RFUParam[arm].is_stopping ) {
00344 std::cerr << "[" << m_profile.instance_name << "] [" << m_qRef.tm << "] ReferenceForceUpdater [" << arm << "] active => inactive." << std::endl;
00345 m_RFUParam[arm].is_active = false;
00346 m_RFUParam[arm].is_stopping = false;
00347 }
00348 }
00349 }
00350
00351 {
00352 bool all_arm_is_not_active = true;
00353 const hrp::Vector3 default_ref_foot_origin_ext_moment = hrp::Vector3::Zero();
00354 for (std::map<std::string, ReferenceForceUpdaterParam>::iterator itr = m_RFUParam.begin(); itr != m_RFUParam.end(); itr++ ) {
00355 std::string arm = itr->first;
00356 size_t arm_idx = ee_index_map[arm];
00357 if ( m_RFUParam[arm].is_active ) all_arm_is_not_active = false;
00358 else {
00359 if ( !isFootOriginExtMoment(arm) ) {
00360 for (unsigned int j=0; j<3; j++ ) ref_force[arm_idx](j) = m_ref_force_in[arm_idx].data[j];
00361 } else {
00362 for (unsigned int j=0; j<3; j++ ) ref_force[arm_idx](j) = default_ref_foot_origin_ext_moment(j);
00363 }
00364 }
00365 }
00366
00367 if ( all_arm_is_not_active ) {
00368 for (unsigned int i=0; i<m_ref_force_in.size(); i++ ){
00369 for (unsigned int j=0; j<6; j++ ) {
00370 m_ref_force_out[i].data[j] = m_ref_force_in[i].data[j];
00371 }
00372 m_ref_force_out[i].tm = m_ref_force_in[i].tm;
00373 m_ref_forceOut[i]->write();
00374 }
00375 m_refFootOriginExtMoment.data.x = default_ref_foot_origin_ext_moment(0);
00376 m_refFootOriginExtMoment.data.y = default_ref_foot_origin_ext_moment(1);
00377 m_refFootOriginExtMoment.data.z = default_ref_foot_origin_ext_moment(2);
00378 m_refFootOriginExtMoment.tm = m_qRef.tm;
00379 m_refFootOriginExtMomentOut.write();
00380 m_refFootOriginExtMomentIsHoldValue.tm = m_qRef.tm;
00381 m_refFootOriginExtMomentIsHoldValue.data = m_RFUParam["footoriginextmoment"].is_hold_value;
00382 m_refFootOriginExtMomentIsHoldValueOut.write();
00383 return RTC::RTC_OK;
00384 }
00385 }
00386
00387
00388 {
00389 hrp::dvector qorg(m_robot->numJoints());
00390
00391
00392 for ( unsigned int i = 0; i < m_robot->numJoints(); i++ ){
00393 qorg[i] = m_robot->joint(i)->q;
00394 m_robot->joint(i)->q = m_qRef.data[i];
00395 }
00396 m_robot->rootLink()->p = hrp::Vector3(m_basePos.data.x, m_basePos.data.y, m_basePos.data.z);
00397 m_robot->rootLink()->R = hrp::rotFromRpy(m_baseRpy.data.r, m_baseRpy.data.p, m_baseRpy.data.y);
00398 m_robot->calcForwardKinematics();
00399 if ( (ee_map.find("rleg") != ee_map.end() && ee_map.find("lleg") != ee_map.end())
00400 && !use_sh_base_pos_rpy ) {
00401
00402
00403
00404
00405
00406 std::vector<hrp::Vector3> foot_pos;
00407 std::vector<hrp::Matrix33> foot_rot;
00408 std::vector<std::string> leg_names;
00409 leg_names.push_back("rleg");
00410 leg_names.push_back("lleg");
00411 for (size_t i = 0; i < leg_names.size(); i++) {
00412 hrp::Link* target_link = m_robot->link(ee_map[leg_names[i]].target_name);
00413 foot_pos.push_back(target_link->p + target_link->R * ee_map[leg_names[i]].localPos);
00414 foot_rot.push_back(target_link->R * ee_map[leg_names[i]].localR);
00415 }
00416 hrp::Vector3 current_foot_mid_pos ((foot_pos[0]+foot_pos[1])/2.0);
00417 hrp::Matrix33 current_foot_mid_rot;
00418 rats::mid_rot(current_foot_mid_rot, 0.5, foot_rot[0], foot_rot[1]);
00419
00420 hrp::Vector3 new_foot_mid_pos(current_foot_mid_pos);
00421 hrp::Matrix33 new_foot_mid_rot;
00422 {
00423 hrp::Vector3 ex = hrp::Vector3::UnitX();
00424 hrp::Vector3 ez = hrp::Vector3::UnitZ();
00425 hrp::Vector3 xv1 (current_foot_mid_rot * ex);
00426 xv1(2) = 0.0;
00427 xv1.normalize();
00428 hrp::Vector3 yv1(ez.cross(xv1));
00429 new_foot_mid_rot(0,0) = xv1(0); new_foot_mid_rot(1,0) = xv1(1); new_foot_mid_rot(2,0) = xv1(2);
00430 new_foot_mid_rot(0,1) = yv1(0); new_foot_mid_rot(1,1) = yv1(1); new_foot_mid_rot(2,1) = yv1(2);
00431 new_foot_mid_rot(0,2) = ez(0); new_foot_mid_rot(1,2) = ez(1); new_foot_mid_rot(2,2) = ez(2);
00432 }
00433
00434 hrp::Matrix33 tmpR (new_foot_mid_rot * current_foot_mid_rot.transpose());
00435 m_robot->rootLink()->p = new_foot_mid_pos + tmpR * (m_robot->rootLink()->p - current_foot_mid_pos);
00436 rats::rotm3times(m_robot->rootLink()->R, tmpR, m_robot->rootLink()->R);
00437 m_robot->calcForwardKinematics();
00438 }
00439 hrp::Vector3 foot_origin_pos;
00440 calcFootOriginCoords(foot_origin_pos, foot_origin_rot);
00441 }
00442
00443 for (std::map<std::string, ReferenceForceUpdaterParam>::iterator itr = m_RFUParam.begin(); itr != m_RFUParam.end(); itr++ ) {
00444
00445 std::string arm = itr->first;
00446 if ( m_RFUParam[arm].is_active && loop % m_RFUParam[arm].update_count == 0 ) {
00447 if ( isFootOriginExtMoment(arm) ) updateRefFootOriginExtMoment(arm);
00448 else updateRefForces(arm);
00449 }
00450 if (!ref_force_interpolator[arm]->isEmpty()) {
00451 ref_force_interpolator[arm]->get(ref_force[ee_index_map[arm]].data(), true);
00452 }
00453 }
00454 }
00455
00456
00457 for (unsigned int i=0; i<m_ref_force_in.size(); i++ ){
00458 for (unsigned int j=0; j<6; j++ ) {
00459 m_ref_force_out[i].data[j] = m_ref_force_in[i].data[j];
00460 }
00461 for (unsigned int j=0; j<3; j++ ) {
00462 m_ref_force_out[i].data[j] = ref_force[i](j) * transition_interpolator_ratio[i] + m_ref_force_in[i].data[j] * (1-transition_interpolator_ratio[i]);
00463 }
00464 m_ref_force_out[i].tm = m_ref_force_in[i].tm;
00465 m_ref_forceOut[i]->write();
00466 }
00467
00468 size_t idx = ee_index_map["footoriginextmoment"];
00469 hrp::Vector3 tmp_moment = (foot_origin_rot.transpose() * ref_force[idx]) * transition_interpolator_ratio[idx];
00470 m_refFootOriginExtMoment.data.x = tmp_moment(0);
00471 m_refFootOriginExtMoment.data.y = tmp_moment(1);
00472 m_refFootOriginExtMoment.data.z = tmp_moment(2);
00473 m_refFootOriginExtMoment.tm = m_qRef.tm;
00474 m_refFootOriginExtMomentOut.write();
00475
00476 return RTC::RTC_OK;
00477 }
00478
00479 void ReferenceForceUpdater::calcFootOriginCoords (hrp::Vector3& foot_origin_pos, hrp::Matrix33& foot_origin_rot)
00480 {
00481 rats::coordinates leg_c[2], tmpc;
00482 hrp::Vector3 ez = hrp::Vector3::UnitZ();
00483 hrp::Vector3 ex = hrp::Vector3::UnitX();
00484 size_t i = 0;
00485 for (std::map<std::string, ee_trans>::iterator itr = ee_map.begin(); itr != ee_map.end(); itr++ ) {
00486 if (itr->first.find("leg") == std::string::npos) continue;
00487 hrp::Link* target = m_robot->sensor<hrp::ForceSensor>(itr->second.sensor_name)->link;
00488 leg_c[i].pos = target->p;
00489 hrp::Vector3 xv1(target->R * ex);
00490 xv1(2)=0.0;
00491 xv1.normalize();
00492 hrp::Vector3 yv1(ez.cross(xv1));
00493 leg_c[i].rot(0,0) = xv1(0); leg_c[i].rot(1,0) = xv1(1); leg_c[i].rot(2,0) = xv1(2);
00494 leg_c[i].rot(0,1) = yv1(0); leg_c[i].rot(1,1) = yv1(1); leg_c[i].rot(2,1) = yv1(2);
00495 leg_c[i].rot(0,2) = ez(0); leg_c[i].rot(1,2) = ez(1); leg_c[i].rot(2,2) = ez(2);
00496 i++;
00497 }
00498
00499 rats::mid_coords(tmpc, 0.5, leg_c[0], leg_c[1]);
00500 foot_origin_pos = tmpc.pos;
00501 foot_origin_rot = tmpc.rot;
00502 }
00503
00504 void ReferenceForceUpdater::updateRefFootOriginExtMoment (const std::string& arm)
00505 {
00506 double interpolation_time = 0;
00507 size_t arm_idx = ee_index_map[arm];
00508 hrp::Vector3 df = foot_origin_rot * (-1 * hrp::Vector3(m_diffFootOriginExtMoment.data.x, m_diffFootOriginExtMoment.data.y, m_diffFootOriginExtMoment.data.z));
00509 if (!m_RFUParam[arm].is_hold_value)
00510 ref_force[arm_idx] = ref_force[arm_idx] + (m_RFUParam[arm].p_gain * transition_interpolator_ratio[arm_idx]) * df;
00511 interpolation_time = (1/m_RFUParam[arm].update_freq) * m_RFUParam[arm].update_time_ratio;
00512 if ( ref_force_interpolator[arm]->isEmpty() ) {
00513 ref_force_interpolator[arm]->setGoal(ref_force[arm_idx].data(), interpolation_time, true);
00514 }
00515 if ( DEBUGP ) {
00516 std::cerr << "[" << m_profile.instance_name << "] Updating reference moment [" << arm << "]" << std::endl;
00517 std::cerr << "[" << m_profile.instance_name << "] diff foot origin ext moment = " << df.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[Nm], interpolation_time = " << interpolation_time << "[s]" << std::endl;
00518 std::cerr << "[" << m_profile.instance_name << "] new foot origin ext moment = " << ref_force[arm_idx].format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[Nm]" << std::endl;
00519 }
00520 };
00521
00522 void ReferenceForceUpdater::updateRefForces (const std::string& arm)
00523 {
00524 hrp::Vector3 internal_force = hrp::Vector3::Zero();
00525 double interpolation_time = 0;
00526 size_t arm_idx = ee_index_map[arm];
00527 hrp::Link* target_link = m_robot->link(ee_map[arm].target_name);
00528 hrp::Vector3 abs_motion_dir, tmp_act_force, df;
00529 hrp::Matrix33 ee_rot, sensor_rot;
00530 ee_rot = target_link->R * ee_map[arm].localR;
00531 if ( m_RFUParam[arm].frame=="local" )
00532 abs_motion_dir = ee_rot * m_RFUParam[arm].motion_dir;
00533 else {
00534 hrp::Matrix33 current_foot_mid_rot;
00535 std::vector<hrp::Matrix33> foot_rot;
00536 std::vector<std::string> leg_names;
00537 leg_names.push_back("rleg");
00538 leg_names.push_back("lleg");
00539 for (size_t i = 0; i < leg_names.size(); i++) {
00540 hrp::Link* target_link = m_robot->link(ee_map[leg_names[i]].target_name);
00541 foot_rot.push_back(target_link->R * ee_map[leg_names[i]].localR);
00542 }
00543 rats::mid_rot(current_foot_mid_rot, 0.5, foot_rot[0], foot_rot[1]);
00544 abs_motion_dir = current_foot_mid_rot * m_RFUParam[arm].motion_dir;
00545 }
00546 for (size_t i = 0; i < 3; i++ ) tmp_act_force(i) = m_force[arm_idx].data[i];
00547 hrp::Sensor* sensor = m_robot->sensor(hrp::Sensor::FORCE, arm_idx);
00548 sensor_rot = sensor->link->R * sensor->localR;
00549 tmp_act_force = sensor_rot * tmp_act_force;
00550
00551 df = tmp_act_force - ref_force[arm_idx];
00552 double inner_product = 0;
00553 if ( ! std::fabs((abs_motion_dir.norm() - 0.0)) < 1e-5 ) {
00554 abs_motion_dir.normalize();
00555 inner_product = df.dot(abs_motion_dir);
00556 if ( ! (inner_product < 0 && ref_force[arm_idx].dot(abs_motion_dir) < 0.0) ) {
00557 hrp::Vector3 in_f = ee_rot * internal_force;
00558 if (!m_RFUParam[arm].is_hold_value)
00559 ref_force[arm_idx] = ref_force[arm_idx].dot(abs_motion_dir) * abs_motion_dir + in_f + (m_RFUParam[arm].p_gain * inner_product * transition_interpolator_ratio[arm_idx]) * abs_motion_dir;
00560 interpolation_time = (1/m_RFUParam[arm].update_freq) * m_RFUParam[arm].update_time_ratio;
00561 if ( ref_force_interpolator[arm]->isEmpty() ) {
00562 ref_force_interpolator[arm]->setGoal(ref_force[arm_idx].data(), interpolation_time, true);
00563 }
00564 }
00565 }
00566 if ( DEBUGP ) {
00567 std::cerr << "[" << m_profile.instance_name << "] Updating reference force [" << arm << "]" << std::endl;
00568 std::cerr << "[" << m_profile.instance_name << "] inner_product = " << inner_product << "[N], ref_force = " << ref_force[arm_idx].dot(abs_motion_dir) << "[N], interpolation_time = " << interpolation_time << "[s]" << std::endl;
00569 std::cerr << "[" << m_profile.instance_name << "] new ref_force = " << ref_force[arm_idx].format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[N]" << std::endl;
00570 std::cerr << "[" << m_profile.instance_name << "] act_force = " << tmp_act_force.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[N]" << std::endl;
00571 std::cerr << "[" << m_profile.instance_name << "] df = " << df.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << "[N]" << std::endl;
00572 }
00573 };
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 bool ReferenceForceUpdater::setReferenceForceUpdaterParam(const std::string& i_name_, const OpenHRP::ReferenceForceUpdaterService::ReferenceForceUpdaterParam& i_param)
00611 {
00612 std::string arm = std::string(i_name_);
00613 std::cerr << "[" << m_profile.instance_name << "] setReferenceForceUpdaterParam [" << i_name_ << "]" << std::endl;
00614 Guard guard(m_mutex);
00615 if ( m_RFUParam.find(i_name_) == m_RFUParam.end() ) {
00616 std::cerr << "[" << m_profile.instance_name << "] Could not found reference force updater param [" << i_name_ << "]" << std::endl;
00617 return false;
00618 }
00619 if ( std::string(i_param.frame) != "local" && std::string(i_param.frame) != "world" ) {
00620 std::cerr << "[" << m_profile.instance_name << "] \"frame\" parameter must be local/world. could not set \"" << std::string(i_param.frame) << "\"" <<std::endl;
00621 return false;
00622 }
00623
00624 if ( m_RFUParam[arm].is_active ) {
00625 if ( !eps_eq(m_RFUParam[arm].update_freq, i_param.update_freq) ) {
00626 std::cerr << "[" << m_profile.instance_name << "] Could not set update_freq because rfu [" << i_name_ << "] is active (current = " << m_RFUParam[arm].update_freq << ", new = " << i_param.update_freq << ")" << std::endl;
00627 return false;
00628 } else {
00629 m_RFUParam[arm].update_freq = i_param.update_freq;
00630 }
00631 if ( !eps_eq(m_RFUParam[arm].update_time_ratio, i_param.update_time_ratio) ) {
00632 std::cerr << "[" << m_profile.instance_name << "] Could not set update_time_ratio because rfu [" << i_name_ << "] is active (current = " << m_RFUParam[arm].update_time_ratio << ", new = " << i_param.update_time_ratio << ")" << std::endl;
00633 return false;
00634 } else {
00635 m_RFUParam[arm].update_time_ratio = i_param.update_time_ratio;
00636 }
00637 if ( m_RFUParam[arm].frame != std::string(i_param.frame) ) {
00638 std::cerr << "[" << m_profile.instance_name << "] Could not set frame because rfu [" << i_name_ << "] is active (current = " << m_RFUParam[arm].frame << ", new = " << i_param.frame << ")" << std::endl;
00639 return false;
00640 } else {
00641 m_RFUParam[arm].frame = i_param.frame;
00642 }
00643 } else {
00644 m_RFUParam[arm].update_freq = i_param.update_freq;
00645 m_RFUParam[arm].update_time_ratio = i_param.update_time_ratio;
00646 m_RFUParam[arm].update_count=round((1/m_RFUParam[arm].update_freq)/m_dt);
00647 m_RFUParam[arm].frame=std::string(i_param.frame);
00648 }
00649
00650 m_RFUParam[arm].p_gain = i_param.p_gain;
00651 m_RFUParam[arm].d_gain = i_param.d_gain;
00652 m_RFUParam[arm].i_gain = i_param.i_gain;
00653 m_RFUParam[arm].is_hold_value = i_param.is_hold_value;
00654 for (size_t i = 0; i < 3; i++ ) m_RFUParam[arm].motion_dir(i) = i_param.motion_dir[i];
00655
00656
00657 std::cerr << "[" << m_profile.instance_name << "] p_gain = " << m_RFUParam[arm].p_gain << ", d_gain = " << m_RFUParam[arm].d_gain << ", i_gain = " << m_RFUParam[arm].i_gain << std::endl;
00658 std::cerr << "[" << m_profile.instance_name << "] update_freq = " << m_RFUParam[arm].update_freq << "[Hz], update_time_ratio = " << m_RFUParam[arm].update_time_ratio << std::endl;
00659 std::cerr << "[" << m_profile.instance_name << "] motion_dir = " << m_RFUParam[arm].motion_dir.format(Eigen::IOFormat(Eigen::StreamPrecision, 0, ", ", ", ", "", "", " [", "]")) << std::endl;
00660 std::cerr << "[" << m_profile.instance_name << "] frame = " << m_RFUParam[arm].frame << ", is_hold_value = " << (m_RFUParam[arm].is_hold_value?"true":"false") << std::endl;
00661 return true;
00662 };
00663
00664 bool ReferenceForceUpdater::getReferenceForceUpdaterParam(const std::string& i_name_, OpenHRP::ReferenceForceUpdaterService::ReferenceForceUpdaterParam_out i_param)
00665 {
00666 std::string arm = std::string(i_name_);
00667 std::cerr << "[" << m_profile.instance_name << "] getReferenceForceUpdaterParam [" << i_name_ << "]" << std::endl;
00668 if ( m_RFUParam.find(i_name_) == m_RFUParam.end() ) {
00669 std::cerr << "[" << m_profile.instance_name << "] Could not found reference force updater param [" << i_name_ << "]" << std::endl;
00670 return false;
00671 }
00672 Guard guard(m_mutex);
00673 i_param->p_gain = m_RFUParam[arm].p_gain;
00674 i_param->d_gain = m_RFUParam[arm].d_gain;
00675 i_param->i_gain = m_RFUParam[arm].i_gain;
00676 i_param->update_freq = m_RFUParam[arm].update_freq;
00677 i_param->update_time_ratio = m_RFUParam[arm].update_time_ratio;
00678 i_param->frame = m_RFUParam[arm].frame.c_str();
00679 i_param->is_hold_value = m_RFUParam[arm].is_hold_value;
00680 for (size_t i = 0; i < 3; i++ ) i_param->motion_dir[i] = m_RFUParam[arm].motion_dir(i);
00681 return true;
00682 };
00683
00684 bool ReferenceForceUpdater::startReferenceForceUpdater(const std::string& i_name_)
00685 {
00686 std::cerr << "[" << m_profile.instance_name << "] startReferenceForceUpdater [" << i_name_ << "]" << std::endl;
00687 {
00688 Guard guard(m_mutex);
00689 if ( m_RFUParam.find(i_name_) == m_RFUParam.end() ) {
00690 std::cerr << "[" << m_profile.instance_name << "] Could not found reference force updater param [" << i_name_ << "]" << std::endl;
00691 return false;
00692 }
00693 if ( m_RFUParam[i_name_].is_active == true )
00694 return true;
00695 if (transition_interpolator[i_name_]->isEmpty()) {
00696 m_RFUParam[i_name_].is_active = true;
00697 double tmpstart = 0.0, tmpgoal = 1.0;
00698 size_t arm_idx = ee_index_map[i_name_];
00699 hrp::Vector3 currentRefForce;
00700 if ( isFootOriginExtMoment(std::string(i_name_)) ) {
00701 currentRefForce = hrp::Vector3 (m_diffFootOriginExtMoment.data.x, m_diffFootOriginExtMoment.data.y, m_diffFootOriginExtMoment.data.z);
00702 } else {
00703 currentRefForce = hrp::Vector3( m_ref_force_in[arm_idx].data[0], m_ref_force_in[arm_idx].data[1], m_ref_force_in[arm_idx].data[2] );
00704 }
00705 ref_force_interpolator[i_name_]->set(currentRefForce.data());
00706 transition_interpolator[i_name_]->set(&tmpstart);
00707 transition_interpolator[i_name_]->setGoal(&tmpgoal, 1.0, true);
00708 } else {
00709 return false;
00710 }
00711 }
00712 while (!transition_interpolator[i_name_]->isEmpty()) usleep(1000);
00713 usleep(1000);
00714 return true;
00715 };
00716
00717 bool ReferenceForceUpdater::stopReferenceForceUpdater(const std::string& i_name_)
00718 {
00719 std::cerr << "[" << m_profile.instance_name << "] stopReferenceForceUpdater [" << i_name_ << "]" << std::endl;
00720 {
00721 Guard guard(m_mutex);
00722 if ( m_RFUParam.find(i_name_) == m_RFUParam.end() ) {
00723 std::cerr << "[" << m_profile.instance_name << "] Could not found reference force updater param [" << i_name_ << "]" << std::endl;
00724 return false;
00725 }
00726 if ( m_RFUParam[i_name_].is_active == false ){
00727 return true;
00728 }
00729 double tmpstart = 1.0, tmpgoal = 0.0;
00730 transition_interpolator[i_name_]->set(&tmpstart);
00731 transition_interpolator[i_name_]->setGoal(&tmpgoal, 1.0, true);
00732 m_RFUParam[i_name_].is_stopping = true;
00733 }
00734 while (!transition_interpolator[i_name_]->isEmpty()) usleep(1000);
00735 usleep(1000);
00736 return true;
00737 };
00738
00739 extern "C"
00740 {
00741
00742 void ReferenceForceUpdaterInit(RTC::Manager* manager)
00743 {
00744 RTC::Properties profile(ReferenceForceUpdater_spec);
00745 manager->registerFactory(profile,
00746 RTC::Create<ReferenceForceUpdater>,
00747 RTC::Delete<ReferenceForceUpdater>);
00748 }
00749
00750 };
00751
00752