00001
00010 #include "ModifiedServo.h"
00011
00012
00013
00014 static const char* modifiedservo_spec[] =
00015 {
00016 "implementation_id", "ModifiedServo",
00017 "type_name", "ModifiedServo",
00018 "description", "ModifiedServo component",
00019 "version", "0.1",
00020 "vendor", "AIST",
00021 "category", "example",
00022 "activity_type", "SPORADIC",
00023 "kind", "DataFlowComponent",
00024 "max_instance", "1",
00025 "language", "C++",
00026 "lang_type", "compile",
00027
00028 ""
00029 };
00030
00031
00032 ModifiedServo::ModifiedServo(RTC::Manager* manager)
00033
00034 : RTC::DataFlowComponentBase(manager),
00035 m_tauRefIn("tauRef", m_tauRef),
00036 m_qRefIn("qRef", m_qRef),
00037 m_qIn("q", m_q),
00038 m_torqueModeIn("torqueMode", m_torqueMode),
00039 m_tauOut("tau", m_tau),
00040
00041 gain_fname(""),
00042 dt(0.005),
00043 dof(0)
00044 {
00045 }
00046
00047 ModifiedServo::~ModifiedServo()
00048 {
00049 }
00050
00051
00052 RTC::ReturnCode_t ModifiedServo::onInitialize()
00053 {
00054
00055
00056
00057 addInPort("tauRef", m_tauRefIn);
00058 addInPort("qRef", m_qRefIn);
00059 addInPort("q", m_qIn);
00060 addInPort("torqueMode", m_torqueModeIn);
00061
00062
00063 addOutPort("tau", m_tauOut);
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 std::cout << m_profile.instance_name << ": onInitialize() " << std::endl;
00079
00080 RTC::Properties & prop = getProperties();
00081
00082 coil::stringTo(dt, prop["dt"].c_str());
00083 coil::stringTo(ref_dt, prop["ref_dt"].c_str());
00084 nstep = ref_dt/dt;
00085 step = nstep;
00086
00087 m_robot = hrp::BodyPtr(new hrp::Body());
00088
00089 RTC::Manager & rtcManager = RTC::Manager::instance();
00090 std::string nameServer = rtcManager.getConfig()["corba.nameservers"];
00091 int comPos = nameServer.find(",");
00092
00093 if (comPos < 0)
00094 comPos = nameServer.length();
00095
00096
00097 nameServer = nameServer.substr(0, comPos);
00098
00099 RTC::CorbaNaming naming(rtcManager.getORB(), nameServer.c_str());
00100
00101 if (!loadBodyFromModelLoader(m_robot, prop["model"].c_str(),
00102 CosNaming::NamingContext::_duplicate(naming.getRootContext())))
00103 std::cerr << "[" << m_profile.instance_name << "] failed to load model "
00104 << "[" << prop["model"] << "]" << std::endl;
00105
00106 return RTC::RTC_OK;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 RTC::ReturnCode_t ModifiedServo::onActivated(RTC::UniqueId ec_id)
00129 {
00130 std::cout << m_profile.instance_name << ": on Activated" << std::endl;
00131
00132 if (m_qIn.isNew()) {
00133 m_qIn.read();
00134 if (dof == 0) {
00135 dof = m_q.data.length();
00136 readGainFile();
00137 }
00138 }
00139
00140 q_old.resize(dof);
00141 qRef_old.resize(dof);
00142
00143 m_tauRef.data.length(dof);
00144 m_qRef.data.length(dof);
00145 m_torqueMode.data.length(dof);
00146
00147 m_tau.data.length(dof);
00148
00149 for (size_t i = 0; i < dof; i++) {
00150 m_tauRef.data[i] = 0.0;
00151 m_qRef.data[i] = qRef_old[i] = q_old[i] = m_q.data[i];
00152 m_torqueMode.data[i] = false;
00153 }
00154
00155 return RTC::RTC_OK;
00156 }
00157
00158 RTC::ReturnCode_t ModifiedServo::onDeactivated(RTC::UniqueId ec_id)
00159 {
00160 std::cout << m_profile.instance_name << ": on Deactivated" << std::endl;
00161
00162 return RTC::RTC_OK;
00163 }
00164
00165 RTC::ReturnCode_t ModifiedServo::onExecute(RTC::UniqueId ec_id)
00166 {
00167 if (m_tauRefIn.isNew())
00168 m_tauRefIn.read();
00169
00170 if (m_qIn.isNew())
00171 m_qIn.read();
00172
00173 if (m_qRefIn.isNew()) {
00174 m_qRefIn.read();
00175 step = nstep;
00176 }
00177
00178 if (m_torqueModeIn.isNew())
00179 m_torqueModeIn.read();
00180
00181 for (size_t i = 0; i < dof; i++) {
00182
00183 double q = m_q.data[i];
00184 double qRef = step > 0 ? qRef_old[i] + (m_qRef.data[i] - qRef_old[i]) / step : qRef_old[i];
00185
00186 double dq = (q - q_old[i]) / dt;
00187 double dqRef = (qRef - qRef_old[i]) / dt;
00188
00189 q_old[i] = q;
00190 qRef_old[i] = qRef;
00191
00192 double tau = m_torqueMode.data[i] ? m_tauRef.data[i] : Pgain[i] * (qRef - q) + Dgain[i] * (dqRef - dq);
00193
00194 double tau_limit = m_robot->joint(i)->torqueConst * m_robot->joint(i)->climit * m_robot->joint(i)->gearRatio;
00195
00196 m_tau.data[i] = std::max(std::min(tau, tau_limit), -tau_limit);
00197 }
00198
00199 step--;
00200
00201 m_tau.tm = m_q.tm;
00202 m_tauOut.write();
00203
00204 return RTC::RTC_OK;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 void ModifiedServo::readGainFile()
00239 {
00240 if (gain_fname == "") {
00241 RTC::Properties & prop = getProperties();
00242 coil::stringTo(gain_fname, prop["pdgains_sim_file_name"].c_str());
00243 }
00244
00245 gain.open(gain_fname.c_str());
00246
00247 if (gain.is_open()) {
00248
00249 double val;
00250
00251 Pgain.resize(dof);
00252 Dgain.resize(dof);
00253
00254 for (unsigned int i = 0; i < dof; i++) {
00255
00256 if (gain >> val)
00257 Pgain[i] = val;
00258 else
00259 std::cout << "[" << m_profile.instance_name << "] Gain file [" << gain_fname << "] is too short" << std::endl;
00260
00261 if (gain >> val)
00262 Dgain[i] = val;
00263 else
00264 std::cout << "[" << m_profile.instance_name << "] Gain file [" << gain_fname << "] is too short" << std::endl;
00265 }
00266
00267 gain.close();
00268
00269 std::cout << "[" << m_profile.instance_name << "] Gain file [" << gain_fname << "] successfully read" << std::endl;
00270 }
00271 else
00272 std::cout << "[" << m_profile.instance_name << "] Gain file [" << gain_fname << "] could not be opened" << std::endl;
00273 }
00274
00275 extern "C"
00276 {
00277
00278 void ModifiedServoInit(RTC::Manager* manager)
00279 {
00280 coil::Properties profile(modifiedservo_spec);
00281 manager->registerFactory(profile,
00282 RTC::Create<ModifiedServo>,
00283 RTC::Delete<ModifiedServo>);
00284 }
00285
00286 };