ReferenceForceUpdater.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00010 #include <rtm/CorbaNaming.h>
00011 #include <hrpModel/Link.h>
00012 #include <hrpModel/Sensor.h>
00013 #include <hrpModel/ModelLoaderUtil.h>
00014 #include <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 // Module specification
00024 // <rtc-template block="module_spec">
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     // Configuration variables
00038     "conf.default.debugLevel", "0",
00039     ""
00040   };
00041 // </rtc-template>
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     // <rtc-template block="initializer">
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     // </rtc-template>
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   // <rtc-template block="bind_config">
00083   // Bind variables and configuration variable
00084   bindParameter("debugLevel", m_debugLevel, "0");
00085 
00086   // </rtc-template>
00087 
00088   // Registration: InPort/OutPort/Service
00089   // <rtc-template block="registration">
00090   // Set InPort buffers
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   // Set service provider to Ports
00101   m_ReferenceForceUpdaterServicePort.registerProvider("service0", "ReferenceForceUpdaterService", m_ReferenceForceUpdaterService);
00102 
00103   // Set service consumers to Ports
00104   // Set CORBA Service Ports
00105   addPort(m_ReferenceForceUpdaterServicePort);
00106 
00107   // Get dt
00108   RTC::Properties& prop = getProperties(); // get properties information from .wrl file
00109   coil::stringTo(m_dt, prop["dt"].c_str());
00110 
00111   // Make m_robot instance
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(), // load robot model for m_robot
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   // Setting for wrench data ports (real + virtual)
00129   std::vector<std::string> fsensor_names;
00130   //   find names for real force sensors
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   // load virtual force sensors
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   //   add ports for all force sensors (real force, input and output of ref_force)
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     // actual inport
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     // ref inport
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     // ref Outport
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   // setting from conf file
00173   // rleg,TARGET_LINK,BASE_LINK,x,y,z,rx,ry,rz,rth #<=pos + rot (axis+angle)
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(); // rotation in VRML is represented by axis + angle
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       //set rfu param
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       //ref_force_interpolator.insert(std::pair<std::string, interpolator*>(ee_name, new interpolator(3, m_dt)));
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     // For FootOriginExtMoment
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   // check if the dof of m_robot match the number of joint in m_robot
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 RTC::ReturnCode_t ReferenceForceUpdater::onStartup(RTC::UniqueId ec_id)
00277 {
00278   return RTC::RTC_OK;
00279 }
00280 */
00281 
00282 /*
00283 RTC::ReturnCode_t ReferenceForceUpdater::onShutdown(RTC::UniqueId ec_id)
00284 {
00285   return RTC::RTC_OK;
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   // check dataport input
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   //syncronize m_robot to the real robot
00333   if ( m_qRef.data.length() ==  m_robot->numJoints() ) {
00334     Guard guard(m_mutex);
00335 
00336     // Interpolator
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     // If RFU is not active
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       //determin ref_force_out from ref_force_in
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     // If RFU is active
00388     {
00389       hrp::dvector qorg(m_robot->numJoints());
00390 
00391       // reference model
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()) // if legged robot
00400            && !use_sh_base_pos_rpy ) {
00401         // TODO
00402         //  Tempolarily modify root coords to fix foot pos rot
00403         //  This will be removed after seq outputs adequate waistRPY discussed in https://github.com/fkanehiro/hrpsys-base/issues/272
00404 
00405         // get current foot mid pos + rot
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         // calculate fix pos + rot
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         // fix root pos + rot to fix "coords" = "current_foot_mid_xx"
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       // Update reference force
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   //determin ref_force_out from ref_force_in
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   // FootOriginExtMoment
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   // Only double support is assumed
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)); // diff = ref - act;
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     // Calc abs force diff
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 RTC::ReturnCode_t ReferenceForceUpdater::onAborting(RTC::UniqueId ec_id)
00577 {
00578 return RTC::RTC_OK;
00579 }
00580 */
00581 
00582 /*
00583 RTC::ReturnCode_t ReferenceForceUpdater::onError(RTC::UniqueId ec_id)
00584 {
00585   return RTC::RTC_OK;
00586 }
00587 */
00588 
00589 /*
00590 RTC::ReturnCode_t ReferenceForceUpdater::onReset(RTC::UniqueId ec_id)
00591 {
00592   return RTC::RTC_OK;
00593 }
00594 */
00595 
00596 /*
00597 RTC::ReturnCode_t ReferenceForceUpdater::onStateUpdate(RTC::UniqueId ec_id)
00598 {
00599   return RTC::RTC_OK;
00600 }
00601 */
00602 
00603 /*
00604 RTC::ReturnCode_t ReferenceForceUpdater::onRateChanged(RTC::UniqueId ec_id)
00605 {
00606   return RTC::RTC_OK;
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   // Parameters which cannot be changed when active
00624   if ( m_RFUParam[arm].is_active ) { // When active, check parameter changing, and if changed, do not change the value.
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 { // When not active, update parameters
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   // Parameters which can be changed regardless of active/inactive
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   // Print values
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 ){//already not active
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 


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