21 #ifndef __XBOTINTERFACE_UTILS_H__
22 #define __XBOTINTERFACE_UTILS_H__
26 #include <boost/filesystem.hpp>
27 #include <boost/algorithm/string.hpp>
34 #include <yaml-cpp/yaml.h>
51 S << 0, -v.z(), v.y(),
69 const Eigen::Matrix3d& actual,
70 Eigen::Vector3d& error)
73 Eigen::Quaterniond q(actual), q_d(ref);
82 error = q.w()*q_d.vec() - q_d.w()*q.vec() - q_d.vec().cross(q.vec());
91 const Eigen::VectorXd& _startPosture,
92 const Eigen::VectorXd& _targetPosture,
93 const double _max_vel,
94 const double traj_time,
96 Eigen::VectorXd& ref_dot,
100 double duration_temp = 0.0;
101 int _vec_size = _startPosture.size();
104 for (
int i=0; i<_vec_size; i++)
106 _t1 = _targetPosture(i) - _startPosture(i);
107 duration_temp = 1.8750 * std::abs(_t1) / _max_vel;
108 if (duration_temp > _duration_)
109 _duration_ = duration_temp;
112 double _time_ = traj_time - init_time;
113 if (_time_>= 0 && _time_<= _duration_)
115 double tr = (_time_/_duration_);
116 double tr2 = tr * tr;
117 double tr3 = tr2 * tr;
118 double s = (6.0 * tr3 * tr2 - 15.0 * tr3 * tr + 10.0 * tr3);
119 double sd = (30.0 * tr3 * tr/_duration_ - 60.0 * tr3/_duration_ + 30.0 * tr2/_duration_);
121 ref = _startPosture + (_targetPosture - _startPosture) * s;
122 ref_dot = (_targetPosture - _startPosture) * sd;
126 ref_dot = 0.0 * _startPosture;
129 ref = _targetPosture;
130 ref_dot = 0.0 * _targetPosture;
139 const double init_pos,
140 const double final_pos,
141 const double max_vel,
142 const double traj_time,
149 length = final_pos - init_pos;
150 time_t = traj_time - init_time;
151 duration = 1.5 * length / max_vel;
152 if (time_t>= 0 && time_t<= duration) {
153 ref = -2.0 * length * std::pow(time_t/duration,3) + 3.0 * length * std::pow(time_t/duration,2) + init_pos;
154 ref_dot = -6.0 * length * std::pow(time_t,2)/std::pow(duration,3) + 6.0 * length * time_t/std::pow(duration,2);
167 template <
typename SignalType>
186 typedef std::shared_ptr<SecondOrderFilter<SignalType>>
Ptr;
192 _reset_has_been_called(false)
201 _reset_has_been_called(false)
204 reset(initial_state);
207 void reset(
const SignalType& initial_state){
208 _reset_has_been_called =
true;
212 _ydd = initial_state;
213 _udd = initial_state;
217 const SignalType&
process(
const SignalType& input){
219 if(!_reset_has_been_called)
reset(input*0);
229 _y = 1.0/_a0 * ( _u + _b1*_ud + _b2*_udd - _a1*_yd - _a2*_ydd );
275 _a0 = 1.0 + 4.0*_eps/(_omega*_ts) + 4.0/std::pow(_omega*_ts, 2.0);
276 _a1 = 2 - 8.0/std::pow(_omega*_ts, 2.0);
277 _a2 = 1.0 + 4.0/std::pow(_omega*_ts, 2.0) - 4.0*_eps/(_omega*_ts);
286 double _a0, _a1, _a2;
288 bool _reset_has_been_called;
290 SignalType _y, _yd, _ydd, _u, _ud, _udd;
294 template<
class SignalType>
303 for(
unsigned int i = 0; i < _channels; ++i){
304 _filters.push_back(filter);
305 _output.push_back(tmp);
309 const std::vector<SignalType>&
process(
const std::vector<SignalType>& input)
311 if(input.size() != _channels)
312 throw std::runtime_error(
"input size != filters size");
314 for(
unsigned int i = 0; i < _channels; ++i){
315 _filters[i].process(input[i]);
316 _output[i] = _filters[i].getOutput();
327 for(
unsigned int i = 0; i < _channels; ++i){
328 _filters[i].reset(init);
335 if(channel >= _channels)
338 _filters[channel].setTimeStep(time_step);
344 if(channel >= _channels)
345 throw std::runtime_error(
"channel out of channels range!");
347 return _filters[channel].getTimeStep();
352 if(channel >= _channels)
355 _filters[channel].setDamping(damping);
361 if(channel >= _channels)
362 throw std::runtime_error(
"channel out of channels range!");
364 return _filters[channel].getDamping();
367 bool setOmega(
const double omega,
const int channel)
369 if(channel >= _channels)
372 _filters[channel].setOmega(omega);
378 if(channel >= _channels)
379 throw std::runtime_error(
"channel out of channels range!");
381 return _filters[channel].getOmega();
390 std::vector<SecondOrderFilter<SignalType>> _filters;
391 std::vector<SignalType> _output;
399 inline std::string
exec(
const char* cmd)
401 FILE* pipe = popen(cmd,
"r");
405 throw std::runtime_error(
"popen() failed");
414 while(fgets(buffer,
sizeof buffer, pipe) != NULL)
425 int retcode = pclose(pipe);
429 throw std::runtime_error(
"child process '" + std::string(cmd) +
"' exited with code " + std::to_string(retcode));
442 if(input_path ==
"" || !(input_path.at(0) ==
'/'))
445 const char* env_p = std::getenv(
"XBOT_ROOT");
450 std::string current_path(env_p);
453 current_path += input_path;
458 std::cerr <<
"ERROR in " << __func__ <<
" : the input path " << input_path <<
" is neither an absolute path nor related with the robotology superbuild. Download it!" << std::endl;
474 std::string cmd =
"set -eu; cd " + wd +
"; /bin/echo " + input_path;
476 std::string cmd_output;
482 catch(std::exception& e)
485 cmd.c_str(), e.what());
490 if(cmd_output.empty())
496 cmd_output = cmd_output.substr(0, cmd_output.size() - 1);
507 const char* env_p = std::getenv(
"XBOT_CONFIG");
510 std::string xbot_config(env_p);
512 std::ifstream fcp(xbot_config, std::ifstream::in);
513 char xbot_config_path[300];
514 fcp.getline (xbot_config_path, 300);
517 return std::string(xbot_config_path);
530 I.block<3,3>(0,0) = R;
531 I.block<3,3>(3,3) = R;
538 template <
typename T>
550 const T&
back()
const;
564 int decrement_mod(
int idx);
569 std::vector<T> _buffer;
573 template <
typename T>
582 template <
typename T>
586 throw std::out_of_range(
"back() called on a empty deque");
589 int back_idx = decrement_mod(_newest);
590 return _buffer.at(back_idx);
595 template <
typename T>
599 throw std::out_of_range(
"back() called on a empty deque");
602 int back_idx = decrement_mod(_newest);
603 return _buffer.at(back_idx);
608 template <
typename T>
615 _newest = decrement_mod(_newest);
616 if( _newest == _oldest )
625 template <
typename T>
632 template <
typename T>
638 _oldest = ( _oldest + 1 ) % N;
648 _newest = ( _newest + 1 ) % N;
654 template <
typename T>
660 else if ( is_empty() ) {
663 else if ( _newest > _oldest ) {
664 return _newest - _oldest;
667 return ( N - _oldest + _newest );
671 template <
typename T>
674 return _oldest == _newest;
677 template <
typename T>
680 return !is_full() && _newest == 0 && _oldest == -1;
683 template <
typename T>
687 return idx >= 0 ? idx : (idx + N);
690 template <
typename T>
699 double goal,
double start_time,
double end_time,
700 double time,
double& x,
double& dx,
double& ddx
704 A << 1.0000, 0, 0, 0, 0, 0,
705 0, 1.0000, 0, 0, 0, 0,
706 0, 0, 0.5000, 0, 0, 0,
707 -10.0000, -6.0000, -1.5000, 10.0000, -4.0000, 0.5000,
708 15.0000, 8.0000, 1.5000, -15.0000, 7.0000, -1.0000,
709 -6.0000, -3.0000, -0.5000, 6.0000, -3.0000, 0.5000;
711 double alpha = (end_time-start_time);
712 alpha = std::max(1e-6, alpha);
713 double tau = (time - start_time)/alpha;
714 tau = std::max(0.0, tau);
715 tau = std::min(tau, 1.0);
718 b << x0, dx0*alpha, ddx0*std::pow(alpha,2.0), goal, 0.0, 0.0;
723 for(
int i = 0; i < 6; i++)
725 t_v(i) = std::pow(tau, i);
726 dt_v(i) = i > 0 ? std::pow(tau, i-1)*i : 0;
727 ddt_v(i) = i > 1 ? std::pow(tau, i-2)*i*(i-1) : 0;
732 dx = coeffs.dot(dt_v)/alpha;
733 ddx = coeffs.dot(ddt_v)/(alpha*alpha);
737 inline bool ReadFile(std::string path_to_file, std::string& file)
739 std::ifstream t(path_to_file);
746 file = std::string((std::istreambuf_iterator<char>(t)),
747 std::istreambuf_iterator<char>());
756 struct tm * timeinfo;
758 memset(buffer, 0, 80*
sizeof(buffer[0]));
761 timeinfo = localtime(&rawtime);
763 strftime(buffer, 80,
"%Y_%m_%d__%H_%M_%S", timeinfo);
765 return std::string(buffer);