output_recorder.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <string>
19 #include <vector>
20 #include <iostream>
21 #include <fstream>
22 
23 #include <ros/ros.h>
24 
27 
28 #include <boost/thread.hpp>
29 #include <tinyxml.h>
30 
31 
33 {
34  ros::NodeHandle nh_twist("twist_controller");
35  ros::NodeHandle nh_identifier("model_identifier");
36 
37  // JointNames
38  if (!nh_.getParam("joint_names", joints_))
39  {
40  ROS_ERROR("Parameter 'joint_names' not set");
41  return false;
42  }
43  dof_ = joints_.size();
44 
45  if (!nh_twist.getParam("chain_base_link", chain_base_link_))
46  {
47  ROS_ERROR("Parameter 'chain_base_link' not set");
48  return false;
49  }
50  if (!nh_twist.getParam("chain_tip_link", chain_tip_link_))
51  {
52  ROS_ERROR("Parameter 'chain_tip_link' not set");
53  return false;
54  }
55 
57  KDL::Tree my_tree;
58  if (!kdl_parser::treeFromParam("/robot_description", my_tree))
59  {
60  ROS_ERROR("Failed to construct kdl tree");
61  return false;
62  }
64  if (chain_.getNrOfJoints() == 0)
65  {
66  ROS_ERROR("Failed to initialize kinematic chain");
67  return false;
68  }
69 
70  // OutputFilePath
71  if (nh_identifier.hasParam("output_file_path"))
72  {
73  nh_identifier.getParam("output_file_path", output_file_path_);
74  }
75  else
76  {
77  output_file_path_ = "/tmp/model_identifier/";
78  ROS_ERROR("No parameter 'output_file_path'! Using default %s", output_file_path_.c_str());
79  }
80  ROS_WARN("'output_file_path'! %s", output_file_path_.c_str());
81 
85 
87  twist_sub_ = nh_twist.subscribe("command_twist_stamped", 1, &OutputRecorder::twistCallback, this);
88 
89  start_ = false;
90  finished_recording_ = false;
91 
92  ROS_INFO("...initialized!");
93  return true;
94 }
95 
97 {
98  tf::Transform trans;
99  double x_dot_lin_in, y_dot_lin_in, z_dot_lin_in;
100  double x_dot_rot_in, y_dot_rot_in, z_dot_rot_in;
101  double x_dot_lin_out, y_dot_lin_out, z_dot_lin_out;
102  double x_dot_rot_out, y_dot_rot_out, z_dot_rot_out;
103  double x_lin_start, y_lin_start, z_lin_start;
104  double x_rot_start, y_rot_start, z_rot_start;
105 
106  std::vector<double> x_dot_lin_integrated, y_dot_lin_integrated, z_dot_lin_integrated;
107  std::vector<double> x_dot_rot_integrated, y_dot_rot_integrated, z_dot_rot_integrated;
108  geometry_msgs::Pose q_soll, q_ist;
109 
110  int iterations = 0;
111  ros::Rate r(100.0);
112 
113  ROS_INFO("Waiting for Twist callback");
114 
115  while (!start_ && ros::ok())
116  {
117  ros::spinOnce();
118  r.sleep();
119  }
120 
121  boost::thread start_thread;
122  start_thread = boost::thread(boost::bind(&OutputRecorder::stopRecording, this));
124  spinner.start();
125  ROS_INFO("Start recording \n Enter any key to stop it.");
126 
127  ros::Time time = ros::Time::now();
128  ros::Time last_update_time = time;
129  ros::Duration period = time - last_update_time;
130 
131  q_ist = getEndeffectorPose();
132  x_lin_start = q_ist.position.x;
133  y_lin_start = q_ist.position.y;
134  z_lin_start = q_ist.position.z;
135 
136  double roll, pitch, yaw;
137  tf::Quaternion q = tf::Quaternion(q_ist.orientation.x, q_ist.orientation.y, q_ist.orientation.z, q_ist.orientation.w);
138  tf::Matrix3x3(q).getRPY(roll, pitch, yaw);
139 
140  while (!finished_recording_)
141  {
142  // start_thread.join();
143  start_thread.interrupt();
144  time = ros::Time::now();
145  period = time - last_update_time;
146  q_ist = getEndeffectorPose();
147 
149  q_x_lin_out = q_ist.position.x;
150  q_y_lin_out = q_ist.position.y;
151  q_z_lin_out = q_ist.position.z;
152  q = tf::Quaternion(q_ist.orientation.x, q_ist.orientation.y, q_ist.orientation.z, q_ist.orientation.w);
153  tf::Matrix3x3(q).getRPY(roll, pitch, yaw);
154 
156  x_dot_lin_in = x_dot_lin_in_;
157  y_dot_lin_in = y_dot_lin_in_;
158  z_dot_lin_in = z_dot_lin_in_;
159  x_dot_rot_in = x_dot_rot_in_;
160  y_dot_rot_in = y_dot_rot_in_;
161  z_dot_rot_in = z_dot_rot_in_;
162 
163  fillDataVectors(x_dot_lin_in, vector_vel_.x(),
164  y_dot_lin_in, vector_vel_.y(),
165  z_dot_lin_in, vector_vel_.z(),
166  x_dot_rot_in, vector_rot_.x(),
167  y_dot_rot_in, vector_rot_.y(),
168  z_dot_rot_in, vector_rot_.z(),
169  q_x_lin_out, q_y_lin_out, q_z_lin_out, roll, pitch, yaw);
170 
171  euler(&x_dot_lin_integrated, vector_vel_.x(), period.toSec());
172  euler(&y_dot_lin_integrated, vector_vel_.y(), period.toSec());
173  euler(&z_dot_lin_integrated, vector_vel_.z(), period.toSec());
174 
175  euler(&x_dot_rot_integrated, vector_rot_.x(), period.toSec());
176  euler(&y_dot_rot_integrated, vector_rot_.y(), period.toSec());
177  euler(&z_dot_rot_integrated, vector_rot_.z(), period.toSec());
178 
179  if (iterations < 1)
180  {
181  time_vec_.push_back(period.toSec());
182  }
183  else
184  {
185  time_vec_.push_back(time_vec_.at(iterations)+period.toSec());
186  }
187  dt_ += period.toSec();
188  iterations++;
189 
190  last_update_time = time;
191  ros::spinOnce();
192  r.sleep();
193  }
194  tcsetattr(kfd, TCSANOW, &cooked);
195 
196  ROS_INFO("Stopped recording... preparing output for octave plot ");
197 
199  writeToMFile("x_linear", &x_dot_lin_vec_in_, &x_dot_lin_vec_out_, &x_lin_vec_out_, &x_dot_lin_integrated);
200  writeToMFile("y_linear", &y_dot_lin_vec_in_, &y_dot_lin_vec_out_, &y_lin_vec_out_, &y_dot_lin_integrated);
201  writeToMFile("z_linear", &z_dot_lin_vec_in_, &z_dot_lin_vec_out_, &z_lin_vec_out_, &z_dot_lin_integrated);
202 
203  writeToMFile("x_angular", &x_dot_rot_vec_in_, &x_dot_rot_vec_out_, &x_rot_vec_out_, &x_dot_rot_integrated);
204  writeToMFile("y_angular", &y_dot_rot_vec_in_, &y_dot_rot_vec_out_, &y_rot_vec_out_, &y_dot_rot_integrated);
205  writeToMFile("z_angular", &z_dot_rot_vec_in_, &z_dot_rot_vec_out_, &z_rot_vec_out_, &z_dot_rot_integrated);
206 
214 
216  stepResponsePlot("x_linear_step", &x_dot_lin_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
217  stepResponsePlot("y_linear_step", &y_dot_lin_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
218  stepResponsePlot("z_linear_step", &z_dot_lin_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
219  stepResponsePlot("x_angular_step", &x_dot_rot_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
220  stepResponsePlot("y_angular_step", &y_dot_rot_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
221  stepResponsePlot("z_angular_step", &z_dot_rot_vec_in_, &x_dot_lin_integrated, &y_dot_lin_integrated, &z_dot_lin_integrated, &x_dot_rot_integrated, &y_dot_rot_integrated, &z_dot_rot_integrated);
222 }
223 
225 {
226  c = 0x0;
227  // get the console in raw mode
228  tcgetattr(kfd, &cooked);
229  memcpy(&raw, &cooked, sizeof(struct termios));
230  raw.c_lflag &= ~(ICANON | ECHO);
231  // Setting a new line, then end of file
232  raw.c_cc[VEOL] = 1;
233  raw.c_cc[VEOF] = 2;
234  tcsetattr(kfd, TCSANOW, &raw);
235 
236  while (ros::ok())
237  {
238  if (read(kfd, &c, 1) < 0)
239  {
240  perror("read():");
241  exit(-1);
242  }
243  if (c == 0x61)
244  {
245  finished_recording_ = true;
246  break;
247  }
248  }
249 }
250 
251 void OutputRecorder::quit(int sig)
252 {
253  tcsetattr(kfd, TCSANOW, &cooked);
254  exit(0);
255 }
256 
257 void OutputRecorder::jointstateCallback(const sensor_msgs::JointState::ConstPtr& msg)
258 {
259  KDL::JntArray q_temp = last_q_;
260  KDL::JntArray q_dot_temp = last_q_dot_;
261  int count = 0;
262 
263  for (unsigned int j = 0; j < dof_; j++)
264  {
265  for (unsigned int i = 0; i < msg->name.size(); i++)
266  {
267  if (strcmp(msg->name[i].c_str(), joints_[j].c_str()) == 0)
268  {
269  q_temp(j) = msg->position[i];
270  q_dot_temp(j) = msg->velocity[i];
271  count++;
272  break;
273  }
274  }
275  }
276 
277  if (count == joints_.size())
278  {
279  KDL::FrameVel FrameVel;
280  last_q_ = q_temp;
281  last_q_dot_ = q_dot_temp;
283 
285  int ret = jntToCartSolver_vel_->JntToCart(jntArrayVel, FrameVel, -1);
286 
287  if (ret >= 0)
288  {
289  KDL::Twist twist = FrameVel.GetTwist();
290  vector_vel_ = twist.vel;
291  vector_rot_ = twist.rot;
292  // ROS_INFO("ist_vel: %f %f %f",twist.vel.x(), twist.vel.y(), twist.vel.z());
293  }
294  else
295  {
296  ROS_WARN("ChainFkSolverVel failed!");
297  }
298  }
299  else
300  {
301  ROS_ERROR("jointstateCallback: received unexpected 'joint_states'");
302  }
303 }
304 
305 void OutputRecorder::twistCallback(const geometry_msgs::TwistStamped::ConstPtr& msg)
306 {
307  start_ = true;
308  x_dot_lin_in_ = msg->twist.linear.x;
309  y_dot_lin_in_ = msg->twist.linear.y;
310  z_dot_lin_in_ = msg->twist.linear.z;
311 
312  x_dot_rot_in_ = msg->twist.angular.x;
313  y_dot_rot_in_ = msg->twist.angular.y;
314  z_dot_rot_in_ = msg->twist.angular.z;
315 }
316 
318 {
319  ros::Time::now();
320  geometry_msgs::Pose pos;
321  tf::StampedTransform stampedTransform;
322 
323  // Get transformation
324  try
325  {
327  }
328  catch (tf::TransformException& ex)
329  {
330  ROS_ERROR("%s", ex.what());
331  }
332 
333  pos.position.x = stampedTransform.getOrigin().x();
334  pos.position.y = stampedTransform.getOrigin().y();
335  pos.position.z = stampedTransform.getOrigin().z();
336  pos.orientation.x = stampedTransform.getRotation()[0];
337  pos.orientation.y = stampedTransform.getRotation()[1];
338  pos.orientation.z = stampedTransform.getRotation()[2];
339  pos.orientation.w = stampedTransform.getRotation()[3];
340 
341  return pos;
342 }
343 
344 double OutputRecorder::calculateLS(std::vector<double>* vec_out, std::vector<double>* vec_in, int model_order, double& a1, double& a2, double& a3, double& b1, double& b2, double& b3)
345 {
346  double err = 0;
347  Eigen::MatrixXd F(vec_out->size()-model_order, model_order*2);
348  Eigen::VectorXd y(vec_out->size()-model_order);
349  Eigen::MatrixXd F_pinv;
350  Eigen::MatrixXd theta;
351  std::vector<double> errorVector;
352  int d = 0;
353 
355  if (model_order == 1)
356  {
357  for (int i = 0; i < vec_out->size()-model_order; i++)
358  {
359  if (i < d)
360  {
361  F(i, 0) = 0;
362  y(i) = 0;
363  }
364  else
365  {
366  F(i, 0) = -1 * vec_out->at(i);
367  y(i) = vec_out->at(i+1);
368  }
369  F(i, 1) = vec_in->at(i);
370  }
371  }
372 
374  if (model_order == 2)
375  {
376  for (int i = 0; i < vec_out->size()-model_order; i++)
377  {
378  if (i < d)
379  {
380  F(i, 0) = 0;
381  F(i, 1) = 0;
382  y(i) = 0;
383  }
384  else
385  {
386  F(i, 0) = -1 * vec_out->at(i+1);
387  F(i, 1) = -1 * vec_out->at(i);
388  y(i) = vec_out->at(i+2);
389  }
390  F(i, 2) = vec_in->at(i+1);
391  F(i, 3) = vec_in->at(i);
392  }
393  }
394 
396  if (model_order == 3)
397  {
398  for (int i = 0; i < vec_out->size()-model_order; i++)
399  {
400  if (i < d)
401  {
402  F(i, 0) = 0;
403  F(i, 1) = 0;
404  F(i, 2) = 0;
405  y(i) = 0;
406  }
407  else
408  {
409  F(i, 0) = -1 * vec_out->at(i+2);
410  F(i, 1) = -1 * vec_out->at(i+1);
411  F(i, 2) = -1 * vec_out->at(i);
412  y(i) = vec_out->at(i+3);
413  }
414  F(i, 3) = vec_in->at(i+2);
415  F(i, 4) = vec_in->at(i+1);
416  F(i, 5) = vec_in->at(i);
417  }
418  }
419 
421  pseudoInverse(F, F_pinv, (2.2204*pow(10, -16)));
422  theta = F_pinv * y;
423  Eigen::MatrixXd e = y - F * theta;
424  Eigen::MatrixXd e_squared = e.transpose() * e;
425  err = e_squared(0, 0);
426 
427  errorVector.push_back(err);
428 
429  a1 = a2 = a3 = b1 = b2 = b3 = 0;
430  if (model_order == 1)
431  {
432  a1 = theta(0, 0);
433  b1 = theta(1, 0);
434  }
435 
436  if (model_order == 2)
437  {
438  a1 = theta(0, 0);
439  a2 = theta(1, 0);
440  b1 = theta(2, 0);
441  b2 = theta(3, 0);
442  }
443 
444  if (model_order == 3)
445  {
446  a1 = theta(0, 0);
447  a2 = theta(1, 0);
448  a3 = theta(2, 0);
449  b1 = theta(3, 0);
450  b2 = theta(4, 0);
451  b3 = theta(5, 0);
452  }
453 
454  std::cout << "\n\nTheta: \n" << theta << std::endl;
455  std::cout << "\n Squared Error: \n" << err << std::endl;
456 
457  return err;
458 }
459 
460 void OutputRecorder::pseudoInverse(const Eigen::MatrixXd& matrix, Eigen::MatrixXd& matrix_inv, double tolerance)
461 {
462  Eigen::JacobiSVD<Eigen::MatrixXd> svdOfM(matrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
463  const Eigen::MatrixXd U = svdOfM.matrixU();
464  const Eigen::MatrixXd V = svdOfM.matrixV();
465  const Eigen::VectorXd S = svdOfM.singularValues();
466  Eigen::VectorXd Sinv = S;
467 
468  double maxsv = 0;
469  for (std::size_t i = 0; i < S.rows(); ++i)
470  {
471  if (fabs(S(i)) > maxsv)
472  {
473  maxsv = fabs(S(i));
474  }
475  }
476 
477  for (std::size_t i = 0; i < S.rows(); ++i)
478  {
479  Sinv(i) = ((S(i)< 0.0001)?0:1/S(i));
480  }
481 
482  matrix_inv = V * Sinv.asDiagonal() * U.transpose();
483 }
484 
485 void OutputRecorder::euler(std::vector<double>* out, double in, double dt)
486 {
487  if (out->size() == 0)
488  {
489  out->push_back(in*dt);
490  }
491  else
492  {
493  out->push_back(out->at(out->size()-1) + in*dt);
494  }
495 }
496 
497 void OutputRecorder::fillDataVectors(double x_dot_lin_in, double x_dot_lin_out,
498  double y_dot_lin_in, double y_dot_lin_out,
499  double z_dot_lin_in, double z_dot_lin_out,
500  double x_dot_rot_in, double x_dot_rot_out,
501  double y_dot_rot_in, double y_dot_rot_out,
502  double z_dot_rot_in, double z_dot_rot_out,
503  double x_lin_out, double y_lin_out, double z_lin_out, double x_rot_out, double y_rot_out, double z_rot_out)
504 {
506  x_dot_lin_vec_in_.push_back(x_dot_lin_in);
507  x_dot_lin_vec_out_.push_back(x_dot_lin_out);
508  y_dot_lin_vec_in_.push_back(y_dot_lin_in);
509  y_dot_lin_vec_out_.push_back(y_dot_lin_out);
510  z_dot_lin_vec_in_.push_back(z_dot_lin_in);
511  z_dot_lin_vec_out_.push_back(z_dot_lin_out);
512 
514  x_dot_rot_vec_in_.push_back(x_dot_rot_in);
515  x_dot_rot_vec_out_.push_back(x_dot_rot_out);
516  y_dot_rot_vec_in_.push_back(y_dot_rot_in);
517  y_dot_rot_vec_out_.push_back(y_dot_rot_out);
518  z_dot_rot_vec_in_.push_back(z_dot_rot_in);
519  z_dot_rot_vec_out_.push_back(z_dot_rot_out);
520 
522  x_lin_vec_out_.push_back(x_lin_out);
523  y_lin_vec_out_.push_back(y_lin_out);
524  z_lin_vec_out_.push_back(z_lin_out);
525 
527  x_rot_vec_out_.push_back(x_rot_out);
528  y_rot_vec_out_.push_back(y_rot_out);
529  z_rot_vec_out_.push_back(z_rot_out);
530 }
531 
532 void OutputRecorder::stepResponsePlot(std::string file_name, std::vector<double>* in, std::vector<double>* x_lin_out, std::vector<double>* y_lin_out, std::vector<double>* z_lin_out, std::vector<double>* x_rot_out, std::vector<double>* y_rot_out, std::vector<double>* z_rot_out)
533 {
534  std::ofstream myfile;
535  std::string name;
536 
537  name = output_file_path_ + file_name + ".m";
538  ROS_INFO("Writing results to: %s", name.c_str());
539  const char* charPath = name.c_str();
540 
541  myfile.open(charPath);
542  myfile << "clear all;close all;\n\n";
543 
545  myfile << file_name << "_in = [" << std::endl;
546  for (int i = 0; i < in->size()-1; i++)
547  {
548  myfile << in->at(i) <<std::endl;
549  }
550  myfile << "]; \n" << std::endl;
551 
552  myfile << file_name << "_x_lin_out = [" << std::endl;
553  for (int i = 0; i < x_lin_out->size()-1; i++)
554  {
555  myfile << x_lin_out->at(i) <<std::endl;
556  }
557  myfile << "]; \n" << std::endl;
558 
559  myfile << file_name << "_y_lin_out = [" << std::endl;
560  for (int i = 0; i < y_lin_out->size()-1; i++)
561  {
562  myfile << y_lin_out->at(i) <<std::endl;
563  }
564  myfile << "]; \n" << std::endl;
565 
566  myfile << file_name << "_z_lin_out = [" << std::endl;
567  for (int i = 0; i < z_lin_out->size()-1; i++)
568  {
569  myfile << z_lin_out->at(i) <<std::endl;
570  }
571  myfile << "]; \n" << std::endl;
572 
573  myfile << file_name << "_x_rot_out = [" << std::endl;
574  for (int i = 0; i < x_rot_out->size()-1; i++)
575  {
576  myfile << x_rot_out->at(i) <<std::endl;
577  }
578  myfile << "]; \n" << std::endl;
579 
580  myfile << file_name << "_y_rot_out = [" << std::endl;
581  for (int i = 0; i < y_rot_out->size()-1; i++)
582  {
583  myfile << y_rot_out->at(i) <<std::endl;
584  }
585  myfile << "]; \n" << std::endl;
586 
587  myfile << file_name << "_z_rot_out = [" << std::endl;
588  for (int i = 0; i < z_rot_out->size()-1; i++)
589  {
590  myfile << z_rot_out->at(i) <<std::endl;
591  }
592  myfile << "]; \n" << std::endl;
593 
594  myfile << "k = size(" <<file_name << "_in);" << std::endl;
595  myfile << "t = linspace(0,k(1)*" << fabs(dt_) << ",size(" <<file_name << "_in));" << std::endl;
596 
597  myfile << "figure" << std::endl;
598  myfile << "plot(t," << file_name << "_in,t," << file_name << "_x_lin_out,t," << file_name << "_y_lin_out,t," << file_name << "_z_lin_out,t," << file_name << "_x_rot_out,t," << file_name << "_y_rot_out,t," << file_name << "_z_rot_out)" << std::endl;
599  myfile << "c=legend('Input','x_lin_out','y_lin_out','z_lin_out','x_rot_out','y_rot_out','z_rot_out','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
600  myfile << "grid" << std::endl;
601 
602  myfile.close();
603 }
604 
605 
606 void OutputRecorder::writeToMFile(std::string file_name, std::vector<double>* dot_in, std::vector<double>* dot_out, std::vector<double>* pos_out, std::vector<double>* dot_integrated)
607 {
608  std::ofstream myfile;
609  std::string name;
610  std::vector <double> errVec;
611  double a1, a2, a3, b1, b2, b3 = 0.0;
612  std::ostringstream a1_str, a2_str, a3_str, b1_str, b2_str, b3_str;
613 
614  name = output_file_path_ + file_name + ".m";
615  ROS_INFO("Writing results to: %s", name.c_str());
616  const char* charPath = name.c_str();
617 
618  myfile.open(charPath);
619 
620  myfile << "clear all;close all;\n\n";
621 
623  myfile << file_name << "_dot_in = [" << std::endl;
624  for (int i = 0; i < dot_in->size()-1; i++)
625  {
626  myfile << dot_in->at(i) <<std::endl;
627  }
628  myfile << "]; \n" << std::endl;
629 
630  myfile << file_name << "_dot_out = [" << std::endl;
631  for (int i = 0; i < dot_out->size()-1; i++)
632  {
633  myfile << dot_out->at(i) <<std::endl;
634  }
635  myfile << "]; \n" << std::endl;
636 
637  myfile << file_name << "_pos_out = [" << std::endl;
638  for (int i = 0; i < pos_out->size()-1; i++)
639  {
640  myfile << pos_out->at(i) <<std::endl;
641  }
642  myfile << "]; \n" << std::endl;
643 
644  myfile << file_name << "_dot_integrated = [" << std::endl;
645  for (int i=0; i < dot_integrated->size()-1; i++)
646  {
647  myfile << dot_integrated->at(i) <<std::endl;
648  }
649  myfile << "]; \n" << std::endl;
650 
651  myfile << "t = [" << std::endl;
652  for (int i = 0; i < time_vec_.size()-1; i++)
653  {
654  myfile << time_vec_.at(i) <<std::endl;
655  }
656  myfile << "]; \n" << std::endl;
658 
660  myfile << "k = size(" <<file_name << "_dot_in);" << std::endl;
661  myfile << "t = linspace(0,k(1)*" << fabs(dt_) << ",size(" <<file_name << "_dot_in));" << std::endl;
663 
665  myfile << "s = tf('s'); z=tf('z',1/50);" << std::endl;
666 
667  errVec.clear();
668 
670  a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
671  a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
672 
673  errVec.push_back(calculateLS(dot_out, dot_in, 1, a1, a2, a3, b1, b2, b3));
674 
675  a1_str << a1;
676  b1_str << b1;
677 
678  std::string Gz1 = "Gz_" + file_name + "1=" + b1_str.str() + "*z^-1/(1" + a1_str.str() + "*z^-1);";
679  while (Gz1.find("+-") != std::string::npos)
680  {
681  Gz1.replace(Gz1.find("+-"), 2, "-");
682  }
683 
684  myfile << Gz1;
685 
687  a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
688  a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
689 
690  errVec.push_back(calculateLS(dot_out, dot_in, 2, a1, a2, a3, b1, b2, b3));
691 
692  a1_str << a1;
693  a2_str << a2;
694 
695  b1_str << b1;
696  b2_str << b2;
697 
698 
699  std::string Gz2 = "Gz_" + file_name + "2=(" + b1_str.str() + "*z^-1 +" + b2_str.str() + "*z^-2)/(1 +" + a1_str.str() + "*z^-1 +" + a2_str.str() + "*z^-2);";
700  while (Gz2.find("+-") != std::string::npos)
701  {
702  Gz2.replace(Gz2.find("+-"), 2, "-");
703  }
704 
705  myfile << Gz2;
706 
707 
709  a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
710  a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
711 
712  errVec.push_back(calculateLS(dot_out, dot_in, 3, a1, a2, a3, b1, b2, b3));
713 
714  a1_str << a1;
715  a2_str << a2;
716  a3_str << a3;
717  b1_str << b1;
718  b2_str << b2;
719  b3_str << b3;
720 
721  std::string Gz3 = "Gz_" + file_name + "3=(" + b1_str.str() + "*z^-1 +" + b2_str.str() + "*z^-2 +" + b3_str.str() + "*z^-3)/(1 +" + a1_str.str() + "*z^-1 +" + a2_str.str() + "*z^-2 +" + a3_str.str() + "*z^-3);";
722  while (Gz3.find("+-") != std::string::npos)
723  {
724  Gz3.replace(Gz3.find("+-"), 2, "-");
725  }
726  myfile << Gz3;
727 
728 
730  myfile << "e =[" << errVec.at(0) << "," << errVec.at(1) << "," << errVec.at(2) << "];" << std::endl;
731  myfile << "figure; semilogy(e); grid;" << std::endl;
732 
733  double step = 0.0;
734  for (int i = 0; i < dot_in->size()-1; i++)
735  {
736  step+=dot_in->at(i);
737  }
738  step/=(dot_in->size()-1);
739  std::cout << "step = " << step <<std::endl;
740 
741  int length = static_cast<int>(pos_out->size()*2/3) - static_cast<int>(pos_out->size()/3);
742  double Ki = (pos_out->at(static_cast<int>(pos_out->size()*2/3)) - pos_out->at(static_cast<int>(pos_out->size()/3)))/(length * dt_) / step;
743 
744  ROS_INFO("length: %i dY: %f Ki: %f", length, (pos_out->at(static_cast<int>(pos_out->size()*2/3)) - pos_out->at(static_cast<int>(pos_out->size()/3))), Ki);
745 
747  myfile << "Gz_" << file_name << "1 = minreal(Gz_" << file_name << "1);" << std::endl;
748  myfile << "Gs_" << file_name << "1=d2c(Gz_" << file_name << "1,'matched');" << std::endl;
749  // myfile << "Gs_" << file_name << "_integrated1 = Gs_" << file_name << "1*(" << Ki << "/s);" << std::endl;
750  myfile << "Gs_" << file_name << "_integrated1 = Gs_" << file_name << "1* (1/s);" << std::endl;
751  myfile << "Gs_" << file_name << "_out1 = lsim(Gs_" << file_name << "1," << file_name << "_dot_in,t);" << std::endl;
752  myfile << "Gs_" << file_name << "_out_integrated1 = lsim(Gs_" << file_name << "_integrated1," << file_name << "_dot_in,t);" << std::endl;
753 
754  // Plot
755  myfile << "figure" << std::endl;
756  myfile << "subplot(2,1,1);" << std::endl;
757  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out1)" << std::endl;
758  myfile << "c=legend('Velocity Input','Velocity Systemresponse','PT1 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
759  myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
760  myfile << "grid" << std::endl;
761  myfile << "subplot(2,1,2);" << std::endl;
762  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated1)" << std::endl;
763  myfile << "c=legend('Velocity Input','Position Systemresponse','IT1 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
764  myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
765  myfile << "grid" << std::endl;
766 
768  myfile << "Gz_" << file_name << "2 = minreal(Gz_" << file_name << "2);"<< std::endl;
769  myfile << "Gs_" << file_name << "2=d2c(Gz_" << file_name << "2,'matched');" << std::endl;
770  // myfile << "Gs_" << file_name << "_integrated2 = Gs_" << file_name << "2*(" << Ki << "/s);" << std::endl;
771  myfile << "Gs_" << file_name << "_integrated2 = Gs_" << file_name << "2*(1/s);" << std::endl;
772  myfile << "Gs_" << file_name << "_out2 = lsim(Gs_" << file_name << "2," << file_name << "_dot_in,t);" << std::endl;
773  myfile << "Gs_" << file_name << "_out_integrated2 = lsim(Gs_" << file_name << "_integrated2," << file_name << "_dot_in,t);" << std::endl;
774 
775  // Plot
776  myfile << "figure" << std::endl;
777  myfile << "subplot(2,1,1);" << std::endl;
778  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out2)" << std::endl;
779  myfile << "c=legend('Velocity Input','Velocity Systemresponse','PDT2 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
780  myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
781  myfile << "grid" << std::endl;
782  myfile << "subplot(2,1,2);" << std::endl;
783  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated2)" << std::endl;
784  myfile << "c=legend('Velocity Input','Position Systemresponse','PIDT2 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
785  myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
786  myfile << "grid" << std::endl;
787 
789  myfile << "Gz_" << file_name << "3 = minreal(Gz_" << file_name << "3);" << std::endl;
790  myfile << "Gs_" << file_name << "3=d2c(Gz_" << file_name << "3,'matched');" << std::endl;
791  // myfile << "Gs_" << file_name << "_integrated3 = Gs_" << file_name << "3*(" << Ki << "/s);" << std::endl;
792  myfile << "Gs_" << file_name << "_integrated3 = Gs_" << file_name << "3*(1/s);" << std::endl;
793  myfile << "Gs_" << file_name << "_out3 = lsim(Gs_" << file_name << "3," << file_name << "_dot_in,t);" << std::endl;
794  myfile << "Gs_" << file_name << "_out_integrated3 = lsim(Gs_" << file_name << "_integrated3," << file_name << "_dot_in,t);" << std::endl;
795 
796  // Plot
797  myfile << "figure" << std::endl;
798  myfile << "subplot(2,1,1);" << std::endl;
799  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out3)" << std::endl;
800  myfile << "c=legend('Velocity Input','Velocity Systemresponse','PD2T3 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
801  myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
802  myfile << "grid" << std::endl;
803  myfile << "subplot(2,1,2);" << std::endl;
804  myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated3)" << std::endl;
805  myfile << "c=legend('Velocity Input','Position Systemresponse','PID2T3 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
806  myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
807  myfile << "grid" << std::endl;
808 
809  myfile.close();
810 }
811 
std::vector< double > x_dot_lin_vec_out_
Outputs.
d
std::vector< double > z_dot_lin_vec_in_
void jointstateCallback(const sensor_msgs::JointState::ConstPtr &msg)
std::vector< double > x_dot_rot_vec_out_
std::vector< double > y_dot_lin_vec_out_
KDL::ChainFkSolverVel_recursive * jntToCartSolver_vel_
ros::NodeHandle nh_
std::vector< double > z_dot_rot_vec_out_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void pseudoInverse(const Eigen::MatrixXd &matrix, Eigen::MatrixXd &matrix_inv, double tolerance)
Vector vel
ros::Subscriber twist_sub_
void writeToMFile(std::string file_name, std::vector< double > *dot_in, std::vector< double > *dot_out, std::vector< double > *pos_out, std::vector< double > *dot_integrated)
IMETHOD Twist GetTwist() const
tf::TransformListener listener_
Transform Listener.
std::vector< double > x_lin_vec_out_
std::vector< double > x_dot_lin_vec_in_
Inputs.
std::vector< double > time_vec_
std::vector< double > z_dot_rot_vec_in_
std::vector< double > y_dot_rot_vec_in_
TFSIMD_FORCE_INLINE const tfScalar & y() const
#define ROS_WARN(...)
void twistCallback(const geometry_msgs::TwistStamped::ConstPtr &msg)
std::vector< double > y_dot_rot_vec_out_
double z() const
void spinner()
KDL::JntArray last_q_dot_
unsigned int dof_
TFSIMD_FORCE_INLINE const tfScalar & x() const
std::vector< double > x_dot_rot_vec_in_
std::vector< double > z_lin_vec_out_
std::vector< double > z_dot_lin_vec_out_
KDL::Vector vector_vel_
TFSIMD_FORCE_INLINE const tfScalar & z() const
KDL::Vector vector_rot_
Vector rot
double y() const
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
std::vector< double > y_rot_vec_out_
#define ROS_INFO(...)
std::vector< double > x_rot_vec_out_
double x() const
ROSCPP_DECL bool ok()
TFSIMD_FORCE_INLINE const tfScalar & y() const
ros::Subscriber jointstate_sub_
unsigned int getNrOfJoints() const
geometry_msgs::Pose getEndeffectorPose()
double calculateLS(std::vector< double > *vec_out, std::vector< double > *vec_in, int model_order, double &a1, double &a2, double &a3, double &b1, double &b2, double &b3)
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
std::vector< double > z_rot_vec_out_
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
KDL::Chain chain_
KDL Conversion.
bool sleep()
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
struct termios cooked raw
void euler(std::vector< double > *out, double in, double dt)
unsigned int step
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
virtual int JntToCart(const JntArrayVel &q_in, FrameVel &out, int segmentNr=-1)
KDL_PARSER_PUBLIC bool treeFromParam(const std::string &param, KDL::Tree &tree)
Quaternion getRotation() const
char c
For Keyboard commands.
bool getParam(const std::string &key, std::string &s) const
void stepResponsePlot(std::string file_name, std::vector< double > *in, std::vector< double > *x_lin_out, std::vector< double > *y_lin_out, std::vector< double > *z_lin_out, std::vector< double > *x_rot_out, std::vector< double > *y_rot_out, std::vector< double > *z_rot_out)
static Time now()
std::string chain_base_link_
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
std::string output_file_path_
KDL::JntArray last_q_
bool hasParam(const std::string &key) const
std::vector< double > y_dot_lin_vec_in_
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
double dt_
Euler Integration.
std::vector< std::string > joints_
void quit(int sig)
std::string chain_tip_link_
std::vector< double > y_lin_vec_out_
void fillDataVectors(double x_dot_lin_in, double x_dot_lin_out, double y_dot_lin_in, double y_dot_lin_out, double z_dot_lin_in, double z_dot_lin_out, double x_dot_rot_in, double x_dot_rot_out, double y_dot_rot_in, double y_dot_rot_out, double z_dot_rot_in, double z_dot_rot_out, double x_lin_out, double y_lin_out, double z_lin_out, double x_rot_out, double y_rot_out, double z_rot_out)


cob_model_identifier
Author(s): Christoph Mark
autogenerated on Thu Apr 8 2021 02:39:44