TorqueFilter.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
10 #include "TorqueFilter.h"
11 #include <rtm/CorbaNaming.h>
12 #include <hrpModel/ModelLoaderUtil.h>
13 #include <hrpUtil/MatrixSolvers.h>
14 
15 #define DEBUGP ((m_debugLevel==1 && loop%200==0) || m_debugLevel > 1 )
16 
17 // Module specification
18 // <rtc-template block="module_spec">
19 static const char* torquefilter_spec[] =
20 {
21  "implementation_id", "TorqueFilter",
22  "type_name", "TorqueFilter",
23  "description", "null component",
24  "version", HRPSYS_PACKAGE_VERSION,
25  "vendor", "AIST",
26  "category", "example",
27  "activity_type", "DataFlowComponent",
28  "max_instance", "10",
29  "language", "C++",
30  "lang_type", "compile",
31  // Configuration variables
32  "conf.default.debugLevel", "0",
33  ""
34 };
35 
36 // without specialization, stringTo only convert 0/1 in bool
37 // namespace coil{
38 // template <>
39 // bool stringTo(bool& val, const char* str)
40 // {
41 // if (str == 0) { return false; }
42 // std::stringstream s;
43 // if ((s << str).fail()) { return false; }
44 // if ((s >> std::boolalpha >> val).fail()) { return false; }
45 // return true;
46 // }
47 // }
48 
49 // </rtc-template>
50 
52  : RTC::DataFlowComponentBase(manager),
53  // <rtc-template block="initializer">
54  m_qCurrentIn("qCurrent", m_qCurrent),
55  m_tauInIn("tauIn", m_tauIn),
56  m_tauOutOut("tauOut", m_tauOut),
57  // </rtc-template>
58  m_debugLevel(0),
59  m_is_gravity_compensation(false)
60 {
61 }
62 
64 {
65 }
66 
67 RTC::ReturnCode_t TorqueFilter::onInitialize()
68 {
69  std::cerr << "[" << m_profile.instance_name << "] onInitialize()" << std::endl;
70  // <rtc-template block="bind_config">
71  // Bind variables and configuration variable
72  bindParameter("debugLevel", m_debugLevel, "0");
73 
74  // </rtc-template>
75 
76  // Registration: InPort/OutPort/Service
77  // <rtc-template block="registration">
78  // Set InPort buffers
79  addInPort("qCurrent", m_qCurrentIn);
80  addInPort("tauIn", m_tauInIn);
81 
82  // Set OutPort buffer
83  addOutPort("tauOut", m_tauOutOut);
84 
85  // Set service provider to Ports
86 
87  // Set service consumers to Ports
88 
89  // Set CORBA Service Ports
90 
91  // </rtc-template>
92 
94  coil::stringTo(m_dt, prop["dt"].c_str());
95 
97 
98  RTC::Manager& rtcManager = RTC::Manager::instance();
99  std::string nameServer = rtcManager.getConfig()["corba.nameservers"];
100  int comPos = nameServer.find(",");
101  if (comPos < 0){
102  comPos = nameServer.length();
103  }
104  nameServer = nameServer.substr(0, comPos);
105  RTC::CorbaNaming naming(rtcManager.getORB(), nameServer.c_str());
106  if (!loadBodyFromModelLoader(m_robot, prop["model"].c_str(),
107  CosNaming::NamingContext::_duplicate(naming.getRootContext())
108  )){
109  std::cerr << "[" << m_profile.instance_name << "] failed to load model[" << prop["model"] << "] in "
110  << m_profile.instance_name << std::endl;
111  return RTC::RTC_ERROR;
112  }
113 
114  // init outport
115  m_tauOut.data.length(m_robot->numJoints());
116 
117  // set gravity compensation flag
118  coil::stringTo(m_is_gravity_compensation, prop["gravity_compensation"].c_str());
119  if (m_debugLevel > 0) {
120  std::cerr << "[" << m_profile.instance_name << "] : gravity compensation flag: " << m_is_gravity_compensation << std::endl;
121  }
122 
123  // set torque offset
124  // offset = -(gear torque in neutral pose)
125  m_torque_offset.resize(m_robot->numJoints());
126  coil::vstring torque_offset = coil::split(prop["torque_offset"], ",");
127  if ( m_torque_offset.size() == torque_offset.size() && m_debugLevel > 0) {
128  for(unsigned int i = 0; i < m_robot->numJoints(); i++){
129  coil::stringTo(m_torque_offset[i], torque_offset[i].c_str());
130  std::cerr << "[" << m_profile.instance_name << "]" << "offset[" << m_robot->joint(i)->name << "]: " << m_torque_offset[i] << std::endl;
131  }
132  } else {
133  if (m_debugLevel > 0) {
134  std::cerr << "[" << m_profile.instance_name << "]" << "Size of torque_offset is not correct." << std::endl;
135  std::cerr << "[" << m_profile.instance_name << "]" << "joints: " << m_robot->numJoints() << std::endl;
136  std::cerr << "[" << m_profile.instance_name << "]" << "offsets: " << torque_offset.size() << std::endl;
137  }
138  }
139 
140  // make filter
141  // filter_dim, fb_coeffs[0], ..., fb_coeffs[filter_dim], ff_coeffs[0], ..., ff_coeffs[filter_dim]
142  coil::vstring torque_filter_params = coil::split(prop["torque_filter_params"], ","); // filter values
143  int filter_dim = 0;
144  std::vector<double> fb_coeffs, ff_coeffs;
145  bool use_default_flag = false;
146  // check size of toruqe_filter_params
147  if ( torque_filter_params.size() > 0 ) {
148  coil::stringTo(filter_dim, torque_filter_params[0].c_str());
149  if (m_debugLevel > 0) {
150  std::cerr << "[" << m_profile.instance_name << "]" << "filter dim: " << filter_dim << std::endl;
151  std::cerr << "[" << m_profile.instance_name << "]" << "torque filter param size: " << torque_filter_params.size() << std::endl;
152  }
153  } else {
154  use_default_flag = true;
155  if (m_debugLevel > 0) {
156  std::cerr<< "[" << m_profile.instance_name << "]" << "There is no torque_filter_params. Use default values." << std::endl;
157  }
158  }
159  if (!use_default_flag && ((filter_dim + 1) * 2 + 1 != (int)torque_filter_params.size()) ) {
160  if (m_debugLevel > 0) {
161  std::cerr<< "[" << m_profile.instance_name << "]" << "Size of torque_filter_params is not correct. Use default values." << std::endl;
162  }
163  use_default_flag = true;
164  }
165  // define parameters
166  if (use_default_flag) {
167  // ex) 2dim butterworth filter sampling = 200[hz] cutoff = 5[hz]
168  // octave$ [a, b] = butter(2, 5/200)
169  // fb_coeffs[0] = 1.00000; <- b0
170  // fb_coeffs[1] = 1.88903; <- -b1
171  // fb_coeffs[2] = -0.89487; <- -b2
172  // ff_coeffs[0] = 0.0014603; <- a0
173  // ff_coeffs[1] = 0.0029206; <- a1
174  // ff_coeffs[2] = 0.0014603; <- a2
175  filter_dim = 2;
176  fb_coeffs.resize(filter_dim+1);
177  fb_coeffs[0] = 1.00000;
178  fb_coeffs[1] = 1.88903;
179  fb_coeffs[2] =-0.89487;
180  ff_coeffs.resize(filter_dim+1);
181  ff_coeffs[0] = 0.0014603;
182  ff_coeffs[1] = 0.0029206;
183  ff_coeffs[2] = 0.0014603;
184  } else {
185  fb_coeffs.resize(filter_dim + 1);
186  ff_coeffs.resize(filter_dim + 1);
187  for (int i = 0; i < filter_dim + 1; i++) {
188  coil::stringTo(fb_coeffs[i], torque_filter_params[i + 1].c_str());
189  coil::stringTo(ff_coeffs[i], torque_filter_params[i + (filter_dim + 2)].c_str());
190  }
191  }
192 
193  if (m_debugLevel > 0) {
194  for (int i = 0; i < filter_dim + 1; i++) {
195  std::cerr << "[" << m_profile.instance_name << "]" << "fb[" << i << "]: " << fb_coeffs[i] << std::endl;
196  std::cerr << "[" << m_profile.instance_name << "]" << "ff[" << i << "]: " << ff_coeffs[i] << std::endl;
197  }
198  }
199 
200  // make filter instance
201  for(unsigned int i = 0; i < m_robot->numJoints(); i++){
202  m_filters.push_back(IIRFilter(filter_dim, fb_coeffs, ff_coeffs, std::string(m_profile.instance_name)));
203  }
204 
205  return RTC::RTC_OK;
206 }
207 
208 
209 
210 /*
211  RTC::ReturnCode_t TorqueFilter::onFinalize()
212  {
213  return RTC::RTC_OK;
214  }
215 */
216 
217 /*
218  RTC::ReturnCode_t TorqueFilter::onStartup(RTC::UniqueId ec_id)
219  {
220  return RTC::RTC_OK;
221  }
222 */
223 
224 /*
225  RTC::ReturnCode_t TorqueFilter::onShutdown(RTC::UniqueId ec_id)
226  {
227  return RTC::RTC_OK;
228  }
229 */
230 
231 RTC::ReturnCode_t TorqueFilter::onActivated(RTC::UniqueId ec_id)
232 {
233  std::cerr << "[" << m_profile.instance_name<< "] onActivated(" << ec_id << ")" << std::endl;
234  return RTC::RTC_OK;
235 }
236 
238 {
239  std::cerr << "[" << m_profile.instance_name<< "] onDeactivated(" << ec_id << ")" << std::endl;
240  return RTC::RTC_OK;
241 }
242 
243 RTC::ReturnCode_t TorqueFilter::onExecute(RTC::UniqueId ec_id)
244 {
245  // std::cout << m_profile.instance_name<< ": onExecute(" << ec_id << ")" << std::endl;
246  static int loop = 0;
247  loop ++;
248 
250  RTC::Time tm;
251  tm.sec = coiltm.sec();
252  tm.nsec = coiltm.usec()*1000;
253 
254  if (m_qCurrentIn.isNew()) {
255  m_qCurrentIn.read();
256  }
257  if (m_tauInIn.isNew()) {
258  m_tauInIn.read();
259  }
260 
261  if (m_tauIn.data.length() == m_robot->numJoints()) {
262  int num_joints = m_robot->numJoints();
263  hrp::dvector g_joint_torque(num_joints);
264  hrp::dvector torque(num_joints);
265 
266  if (m_qCurrent.data.length() == m_robot->numJoints()) {
267  // reference robot model
268  for ( unsigned int i = 0; i < m_robot->numJoints(); i++ ){
269  m_robot->joint(i)->q = m_qCurrent.data[i];
270  }
271  m_robot->calcForwardKinematics();
272  m_robot->calcCM();
273  m_robot->rootLink()->calcSubMassCM();
274 
275  // calc gravity compensation of each joints
276  hrp::Vector3 g(0, 0, 9.8);
277  for (int i = 0; i < num_joints; i++) {
278  // subm*g x (submwc/subm - p) . R*a
279  g_joint_torque[i] = (m_robot->joint(i)->subm*g).cross(m_robot->joint(i)->submwc / m_robot->joint(i)->subm - m_robot->joint(i)->p).dot(m_robot->joint(i)->R * m_robot->joint(i)->a);
280  }
281  } else {
282  if (DEBUGP) {
283  std::cerr << "[" << m_profile.instance_name << "]" << "input is not correct" << std::endl;
284  std::cerr << "[" << m_profile.instance_name << "]" << " numJoints: " << m_robot->numJoints() << std::endl;
285  std::cerr << "[" << m_profile.instance_name << "]" << " qCurrent: " << m_qCurrent.data.length() << std::endl;
286  std::cerr << std::endl;
287  }
288  for (int i = 0; i < num_joints; i++) {
289  g_joint_torque[i] = 0.0;
290  }
291  }
292 
293  if (DEBUGP) {
294  std::cerr << "[" << m_profile.instance_name << "]" << "raw torque: ";
295  for (int i = 0; i < num_joints; i++) {
296  std::cerr << " " << m_tauIn.data[i] ;
297  }
298  std::cerr << std::endl;
299  std::cerr << "[" << m_profile.instance_name << "]" << "gravity compensation: ";
300  for (int i = 0; i < num_joints; i++) {
301  std::cerr << " " << g_joint_torque[i];
302  }
303  std::cerr << std::endl;
304  }
305 
306  for (int i = 0; i < num_joints; i++) {
307  // torque calculation from electric current
308  // torque[j] = m_tauIn.data[path->joint(j)->jointId] - joint_torque(j);
309  // torque[j] = m_filters[path->joint(j)->jointId].executeFilter(m_tauIn.data[path->joint(j)->jointId]) - joint_torque(j); // use filtered tau
310  torque[i] = m_filters[i].executeFilter(m_tauIn.data[i]) - m_torque_offset[i];
311 
312  // torque calclation from error of joint angle
313  // if ( m_error_to_torque_gain[path->joint(j)->jointId] == 0.0
314  // || fabs(joint_error(j)) < m_error_dead_zone[path->joint(j)->jointId] ) {
315  // torque[j] = 0;
316  // } else {
317  // torque[j] = error2torque(j, fabs(m_error_dead_zone[path->joint(j)->jointId]));
318  // }
319 
320  // set output
321  // gravity compensation
323  m_tauOut.data[i] = torque[i] + g_joint_torque[i];
324  } else {
325  m_tauOut.data[i] = torque[i];
326  }
327  }
328  if (DEBUGP) {
329  std::cerr << "[" << m_profile.instance_name << "]" << "filtered torque: ";
330  for (int i = 0; i < num_joints; i++) {
331  std::cerr << " " << torque[i];
332  }
333  std::cerr << std::endl;
334  }
335  m_tauOut.tm = tm;
336  m_tauOutOut.write();
337  } else {
338  if (DEBUGP) {
339  std::cerr << "[" << m_profile.instance_name << "]" << "input is not correct" << std::endl;
340  std::cerr << "[" << m_profile.instance_name << "]" << " numJoints: " << m_robot->numJoints() << std::endl;
341  std::cerr << "[" << m_profile.instance_name << "]" << " tauIn: " << m_tauIn.data.length() << std::endl;
342  std::cerr << std::endl;
343  }
344  }
345 
346  return RTC::RTC_OK;
347 }
348 
349 /*
350  RTC::ReturnCode_t TorqueFilter::onAborting(RTC::UniqueId ec_id)
351  {
352  return RTC::RTC_OK;
353  }
354 */
355 
356 /*
357  RTC::ReturnCode_t TorqueFilter::onError(RTC::UniqueId ec_id)
358  {
359  return RTC::RTC_OK;
360  }
361 */
362 
363 /*
364  RTC::ReturnCode_t TorqueFilter::onReset(RTC::UniqueId ec_id)
365  {
366  return RTC::RTC_OK;
367  }
368 */
369 
370 /*
371  RTC::ReturnCode_t TorqueFilter::onStateUpdate(RTC::UniqueId ec_id)
372  {
373  return RTC::RTC_OK;
374  }
375 */
376 
377 /*
378  RTC::ReturnCode_t TorqueFilter::onRateChanged(RTC::UniqueId ec_id)
379  {
380  return RTC::RTC_OK;
381  }
382 */
383 
384 
385 
386 extern "C"
387 {
388 
390  {
392  manager->registerFactory(profile,
393  RTC::Create<TorqueFilter>,
394  RTC::Delete<TorqueFilter>);
395  }
396 
397 };
398 
399 
ComponentProfile m_profile
png_infop png_charpp int png_charpp profile
void TorqueFilterInit(RTC::Manager *manager)
TorqueFilter(RTC::Manager *manager)
Constructor.
static const char * torquefilter_spec[]
long int sec() const
virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id)
bool stringTo(To &val, const char *str)
bool m_is_gravity_compensation
Definition: TorqueFilter.h:152
TimedDoubleSeq m_tauOut
Definition: TorqueFilter.h:113
InPort< TimedDoubleSeq > m_tauInIn
Definition: TorqueFilter.h:118
vstring split(const std::string &input, const std::string &delimiter, bool ignore_empty)
hrp::BodyPtr m_robot
Definition: TorqueFilter.h:148
CORBA::ORB_ptr getORB()
png_uint_32 i
Eigen::VectorXd dvector
coil::Properties & getProperties()
static Manager & instance()
bool addOutPort(const char *name, OutPortBase &outport)
boost::shared_ptr< Body > BodyPtr
Eigen::Vector3d Vector3
std::vector< std::string > vstring
virtual ~TorqueFilter()
Destructor.
int gettimeofday(struct timeval *tv, struct timezone *tz)
coil::Properties & getConfig()
ExecutionContextHandle_t UniqueId
bool bindParameter(const char *param_name, VarType &var, const char *def_val, bool(*trans)(VarType &, const char *)=coil::stringTo)
int loadBodyFromModelLoader(::World *world, const char *name, const char *url, CosNaming::NamingContext_var cxt)
virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id)
std::vector< IIRFilter > m_filters
Definition: TorqueFilter.h:151
virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id)
prop
naming
Vector3 cross(const Vector3 &v1, const Vector3 &v2)
double dot(const Vector3 &v1, const Vector3 &v2)
virtual RTC::ReturnCode_t onInitialize()
InPort< TimedDoubleSeq > m_qCurrentIn
Definition: TorqueFilter.h:117
OutPort< TimedDoubleSeq > m_tauOutOut
Definition: TorqueFilter.h:124
unsigned int m_debugLevel
Definition: TorqueFilter.h:149
virtual bool isNew()
null component
virtual bool write(DataType &value)
std::vector< double > m_torque_offset
Definition: TorqueFilter.h:150
long int usec() const
TimedDoubleSeq m_tauIn
Definition: TorqueFilter.h:112
bool addInPort(const char *name, InPortBase &inport)
TimedDoubleSeq m_qCurrent
Definition: TorqueFilter.h:111
bool registerFactory(coil::Properties &profile, RtcNewFunc new_func, RtcDeleteFunc delete_func)
#define DEBUGP


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:51