00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <string>
00019 #include <vector>
00020 #include <iostream>
00021 #include <fstream>
00022
00023 #include <ros/ros.h>
00024
00025 #include <tf/transform_broadcaster.h>
00026 #include <cob_model_identifier/output_recorder.h>
00027
00028 #include <boost/thread.hpp>
00029 #include <tinyxml.h>
00030
00031
00032 bool OutputRecorder::initialize()
00033 {
00034 ros::NodeHandle nh_twist("twist_controller");
00035 ros::NodeHandle nh_identifier("model_identifier");
00036
00037
00038 if (!nh_.getParam("joint_names", joints_))
00039 {
00040 ROS_ERROR("Parameter 'joint_names' not set");
00041 return false;
00042 }
00043 dof_ = joints_.size();
00044
00045 if (!nh_twist.getParam("chain_base_link", chain_base_link_))
00046 {
00047 ROS_ERROR("Parameter 'chain_base_link' not set");
00048 return false;
00049 }
00050 if (!nh_twist.getParam("chain_tip_link", chain_tip_link_))
00051 {
00052 ROS_ERROR("Parameter 'chain_tip_link' not set");
00053 return false;
00054 }
00055
00057 KDL::Tree my_tree;
00058 if (!kdl_parser::treeFromParam("/robot_description", my_tree))
00059 {
00060 ROS_ERROR("Failed to construct kdl tree");
00061 return false;
00062 }
00063 my_tree.getChain(chain_base_link_, chain_tip_link_, chain_);
00064 if (chain_.getNrOfJoints() == 0)
00065 {
00066 ROS_ERROR("Failed to initialize kinematic chain");
00067 return false;
00068 }
00069
00070
00071 if (nh_identifier.hasParam("output_file_path"))
00072 {
00073 nh_identifier.getParam("output_file_path", output_file_path_);
00074 }
00075 else
00076 {
00077 output_file_path_ = "/tmp/model_identifier/";
00078 ROS_ERROR("No parameter 'output_file_path'! Using default %s", output_file_path_.c_str());
00079 }
00080 ROS_WARN("'output_file_path'! %s", output_file_path_.c_str());
00081
00083 last_q_ = KDL::JntArray(chain_.getNrOfJoints());
00084 last_q_dot_ = KDL::JntArray(chain_.getNrOfJoints());
00085
00086 jointstate_sub_ = nh_.subscribe("joint_states", 1, &OutputRecorder::jointstateCallback, this);
00087 twist_sub_ = nh_twist.subscribe("command_twist_stamped", 1, &OutputRecorder::twistCallback, this);
00088
00089 start_ = false;
00090 finished_recording_ = false;
00091
00092 ROS_INFO("...initialized!");
00093 return true;
00094 }
00095
00096 void OutputRecorder::run()
00097 {
00098 tf::Transform trans;
00099 double x_dot_lin_in, y_dot_lin_in, z_dot_lin_in;
00100 double x_dot_rot_in, y_dot_rot_in, z_dot_rot_in;
00101 double x_dot_lin_out, y_dot_lin_out, z_dot_lin_out;
00102 double x_dot_rot_out, y_dot_rot_out, z_dot_rot_out;
00103 double x_lin_start, y_lin_start, z_lin_start;
00104 double x_rot_start, y_rot_start, z_rot_start;
00105
00106 std::vector<double> x_dot_lin_integrated, y_dot_lin_integrated, z_dot_lin_integrated;
00107 std::vector<double> x_dot_rot_integrated, y_dot_rot_integrated, z_dot_rot_integrated;
00108 geometry_msgs::Pose q_soll, q_ist;
00109
00110 int iterations = 0;
00111 ros::Rate r(100.0);
00112
00113 ROS_INFO("Waiting for Twist callback");
00114
00115 while (!start_ && ros::ok())
00116 {
00117 ros::spinOnce();
00118 r.sleep();
00119 }
00120
00121 boost::thread start_thread;
00122 start_thread = boost::thread(boost::bind(&OutputRecorder::stopRecording, this));
00123 ros::AsyncSpinner spinner(0);
00124 spinner.start();
00125 ROS_INFO("Start recording \n Enter any key to stop it.");
00126
00127 ros::Time time = ros::Time::now();
00128 ros::Time last_update_time = time;
00129 ros::Duration period = time - last_update_time;
00130
00131 q_ist = getEndeffectorPose();
00132 x_lin_start = q_ist.position.x;
00133 y_lin_start = q_ist.position.y;
00134 z_lin_start = q_ist.position.z;
00135
00136 double roll, pitch, yaw;
00137 tf::Quaternion q = tf::Quaternion(q_ist.orientation.x, q_ist.orientation.y, q_ist.orientation.z, q_ist.orientation.w);
00138 tf::Matrix3x3(q).getRPY(roll, pitch, yaw);
00139
00140 while (!finished_recording_)
00141 {
00142
00143 start_thread.interrupt();
00144 time = ros::Time::now();
00145 period = time - last_update_time;
00146 q_ist = getEndeffectorPose();
00147
00149 q_x_lin_out = q_ist.position.x;
00150 q_y_lin_out = q_ist.position.y;
00151 q_z_lin_out = q_ist.position.z;
00152 q = tf::Quaternion(q_ist.orientation.x, q_ist.orientation.y, q_ist.orientation.z, q_ist.orientation.w);
00153 tf::Matrix3x3(q).getRPY(roll, pitch, yaw);
00154
00156 x_dot_lin_in = x_dot_lin_in_;
00157 y_dot_lin_in = y_dot_lin_in_;
00158 z_dot_lin_in = z_dot_lin_in_;
00159 x_dot_rot_in = x_dot_rot_in_;
00160 y_dot_rot_in = y_dot_rot_in_;
00161 z_dot_rot_in = z_dot_rot_in_;
00162
00163 fillDataVectors(x_dot_lin_in, vector_vel_.x(),
00164 y_dot_lin_in, vector_vel_.y(),
00165 z_dot_lin_in, vector_vel_.z(),
00166 x_dot_rot_in, vector_rot_.x(),
00167 y_dot_rot_in, vector_rot_.y(),
00168 z_dot_rot_in, vector_rot_.z(),
00169 q_x_lin_out, q_y_lin_out, q_z_lin_out, roll, pitch, yaw);
00170
00171 euler(&x_dot_lin_integrated, vector_vel_.x(), period.toSec());
00172 euler(&y_dot_lin_integrated, vector_vel_.y(), period.toSec());
00173 euler(&z_dot_lin_integrated, vector_vel_.z(), period.toSec());
00174
00175 euler(&x_dot_rot_integrated, vector_rot_.x(), period.toSec());
00176 euler(&y_dot_rot_integrated, vector_rot_.y(), period.toSec());
00177 euler(&z_dot_rot_integrated, vector_rot_.z(), period.toSec());
00178
00179 if (iterations < 1)
00180 {
00181 time_vec_.push_back(period.toSec());
00182 }
00183 else
00184 {
00185 time_vec_.push_back(time_vec_.at(iterations)+period.toSec());
00186 }
00187 dt_ += period.toSec();
00188 iterations++;
00189
00190 last_update_time = time;
00191 ros::spinOnce();
00192 r.sleep();
00193 }
00194 tcsetattr(kfd, TCSANOW, &cooked);
00195
00196 ROS_INFO("Stopped recording... preparing output for octave plot ");
00197
00199 writeToMFile("x_linear", &x_dot_lin_vec_in_, &x_dot_lin_vec_out_, &x_lin_vec_out_, &x_dot_lin_integrated);
00200 writeToMFile("y_linear", &y_dot_lin_vec_in_, &y_dot_lin_vec_out_, &y_lin_vec_out_, &y_dot_lin_integrated);
00201 writeToMFile("z_linear", &z_dot_lin_vec_in_, &z_dot_lin_vec_out_, &z_lin_vec_out_, &z_dot_lin_integrated);
00202
00203 writeToMFile("x_angular", &x_dot_rot_vec_in_, &x_dot_rot_vec_out_, &x_rot_vec_out_, &x_dot_rot_integrated);
00204 writeToMFile("y_angular", &y_dot_rot_vec_in_, &y_dot_rot_vec_out_, &y_rot_vec_out_, &y_dot_rot_integrated);
00205 writeToMFile("z_angular", &z_dot_rot_vec_in_, &z_dot_rot_vec_out_, &z_rot_vec_out_, &z_dot_rot_integrated);
00206
00208 stepResponsePlot("x_linear_dot_step", &x_dot_lin_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00209 stepResponsePlot("y_linear_dot_step", &y_dot_lin_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00210 stepResponsePlot("z_linear_dot_step", &z_dot_lin_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00211 stepResponsePlot("x_angular_dot_step", &x_dot_rot_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00212 stepResponsePlot("y_angular_dot_step", &y_dot_rot_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00213 stepResponsePlot("z_angular_dot_step", &z_dot_rot_vec_in_, &x_dot_lin_vec_out_, &y_dot_lin_vec_out_, &z_dot_lin_vec_out_, &x_dot_rot_vec_out_, &y_dot_rot_vec_out_, &z_dot_rot_vec_out_);
00214
00216 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);
00217 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);
00218 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);
00219 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);
00220 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);
00221 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);
00222 }
00223
00224 void OutputRecorder::stopRecording()
00225 {
00226 c = 0x0;
00227
00228 tcgetattr(kfd, &cooked);
00229 memcpy(&raw, &cooked, sizeof(struct termios));
00230 raw.c_lflag &= ~(ICANON | ECHO);
00231
00232 raw.c_cc[VEOL] = 1;
00233 raw.c_cc[VEOF] = 2;
00234 tcsetattr(kfd, TCSANOW, &raw);
00235
00236 while (ros::ok())
00237 {
00238 if (read(kfd, &c, 1) < 0)
00239 {
00240 perror("read():");
00241 exit(-1);
00242 }
00243 if (c == 0x61)
00244 {
00245 finished_recording_ = true;
00246 break;
00247 }
00248 }
00249 }
00250
00251 void OutputRecorder::quit(int sig)
00252 {
00253 tcsetattr(kfd, TCSANOW, &cooked);
00254 exit(0);
00255 }
00256
00257 void OutputRecorder::jointstateCallback(const sensor_msgs::JointState::ConstPtr& msg)
00258 {
00259 KDL::JntArray q_temp = last_q_;
00260 KDL::JntArray q_dot_temp = last_q_dot_;
00261 int count = 0;
00262
00263 for (unsigned int j = 0; j < dof_; j++)
00264 {
00265 for (unsigned int i = 0; i < msg->name.size(); i++)
00266 {
00267 if (strcmp(msg->name[i].c_str(), joints_[j].c_str()) == 0)
00268 {
00269 q_temp(j) = msg->position[i];
00270 q_dot_temp(j) = msg->velocity[i];
00271 count++;
00272 break;
00273 }
00274 }
00275 }
00276
00277 if (count == joints_.size())
00278 {
00279 KDL::FrameVel FrameVel;
00280 last_q_ = q_temp;
00281 last_q_dot_ = q_dot_temp;
00282 KDL::JntArrayVel jntArrayVel = KDL::JntArrayVel(last_q_, last_q_dot_);
00283
00284 jntToCartSolver_vel_ = new KDL::ChainFkSolverVel_recursive(chain_);
00285 int ret = jntToCartSolver_vel_->JntToCart(jntArrayVel, FrameVel, -1);
00286
00287 if (ret >= 0)
00288 {
00289 KDL::Twist twist = FrameVel.GetTwist();
00290 vector_vel_ = twist.vel;
00291 vector_rot_ = twist.rot;
00292
00293 }
00294 else
00295 {
00296 ROS_WARN("ChainFkSolverVel failed!");
00297 }
00298 }
00299 else
00300 {
00301 ROS_ERROR("jointstateCallback: received unexpected 'joint_states'");
00302 }
00303 }
00304
00305 void OutputRecorder::twistCallback(const geometry_msgs::TwistStamped::ConstPtr& msg)
00306 {
00307 start_ = true;
00308 x_dot_lin_in_ = msg->twist.linear.x;
00309 y_dot_lin_in_ = msg->twist.linear.y;
00310 z_dot_lin_in_ = msg->twist.linear.z;
00311
00312 x_dot_rot_in_ = msg->twist.angular.x;
00313 y_dot_rot_in_ = msg->twist.angular.y;
00314 z_dot_rot_in_ = msg->twist.angular.z;
00315 }
00316
00317 geometry_msgs::Pose OutputRecorder::getEndeffectorPose()
00318 {
00319 ros::Time::now();
00320 geometry_msgs::Pose pos;
00321 tf::StampedTransform stampedTransform;
00322
00323
00324 try
00325 {
00326 listener_.lookupTransform(chain_base_link_, chain_tip_link_, ros::Time(0), stampedTransform);
00327 }
00328 catch (tf::TransformException& ex)
00329 {
00330 ROS_ERROR("%s", ex.what());
00331 }
00332
00333 pos.position.x = stampedTransform.getOrigin().x();
00334 pos.position.y = stampedTransform.getOrigin().y();
00335 pos.position.z = stampedTransform.getOrigin().z();
00336 pos.orientation.x = stampedTransform.getRotation()[0];
00337 pos.orientation.y = stampedTransform.getRotation()[1];
00338 pos.orientation.z = stampedTransform.getRotation()[2];
00339 pos.orientation.w = stampedTransform.getRotation()[3];
00340
00341 return pos;
00342 }
00343
00344 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)
00345 {
00346 double err = 0;
00347 Eigen::MatrixXd F(vec_out->size()-model_order, model_order*2);
00348 Eigen::VectorXd y(vec_out->size()-model_order);
00349 Eigen::MatrixXd F_pinv;
00350 Eigen::MatrixXd theta;
00351 std::vector<double> errorVector;
00352 int d = 0;
00353
00355 if (model_order == 1)
00356 {
00357 for (int i = 0; i < vec_out->size()-model_order; i++)
00358 {
00359 if (i < d)
00360 {
00361 F(i, 0) = 0;
00362 y(i) = 0;
00363 }
00364 else
00365 {
00366 F(i, 0) = -1 * vec_out->at(i);
00367 y(i) = vec_out->at(i+1);
00368 }
00369 F(i, 1) = vec_in->at(i);
00370 }
00371 }
00372
00374 if (model_order == 2)
00375 {
00376 for (int i = 0; i < vec_out->size()-model_order; i++)
00377 {
00378 if (i < d)
00379 {
00380 F(i, 0) = 0;
00381 F(i, 1) = 0;
00382 y(i) = 0;
00383 }
00384 else
00385 {
00386 F(i, 0) = -1 * vec_out->at(i+1);
00387 F(i, 1) = -1 * vec_out->at(i);
00388 y(i) = vec_out->at(i+2);
00389 }
00390 F(i, 2) = vec_in->at(i+1);
00391 F(i, 3) = vec_in->at(i);
00392 }
00393 }
00394
00396 if (model_order == 3)
00397 {
00398 for (int i = 0; i < vec_out->size()-model_order; i++)
00399 {
00400 if (i < d)
00401 {
00402 F(i, 0) = 0;
00403 F(i, 1) = 0;
00404 F(i, 2) = 0;
00405 y(i) = 0;
00406 }
00407 else
00408 {
00409 F(i, 0) = -1 * vec_out->at(i+2);
00410 F(i, 1) = -1 * vec_out->at(i+1);
00411 F(i, 2) = -1 * vec_out->at(i);
00412 y(i) = vec_out->at(i+3);
00413 }
00414 F(i, 3) = vec_in->at(i+2);
00415 F(i, 4) = vec_in->at(i+1);
00416 F(i, 5) = vec_in->at(i);
00417 }
00418 }
00419
00421 pseudoInverse(F, F_pinv, (2.2204*pow(10, -16)));
00422 theta = F_pinv * y;
00423 Eigen::MatrixXd e = y - F * theta;
00424 Eigen::MatrixXd e_squared = e.transpose() * e;
00425 err = e_squared(0, 0);
00426
00427 errorVector.push_back(err);
00428
00429 a1 = a2 = a3 = b1 = b2 = b3 = 0;
00430 if (model_order == 1)
00431 {
00432 a1 = theta(0, 0);
00433 b1 = theta(1, 0);
00434 }
00435
00436 if (model_order == 2)
00437 {
00438 a1 = theta(0, 0);
00439 a2 = theta(1, 0);
00440 b1 = theta(2, 0);
00441 b2 = theta(3, 0);
00442 }
00443
00444 if (model_order == 3)
00445 {
00446 a1 = theta(0, 0);
00447 a2 = theta(1, 0);
00448 a3 = theta(2, 0);
00449 b1 = theta(3, 0);
00450 b2 = theta(4, 0);
00451 b3 = theta(5, 0);
00452 }
00453
00454 std::cout << "\n\nTheta: \n" << theta << std::endl;
00455 std::cout << "\n Squared Error: \n" << err << std::endl;
00456
00457 return err;
00458 }
00459
00460 void OutputRecorder::pseudoInverse(const Eigen::MatrixXd& matrix, Eigen::MatrixXd& matrix_inv, double tolerance)
00461 {
00462 Eigen::JacobiSVD<Eigen::MatrixXd> svdOfM(matrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
00463 const Eigen::MatrixXd U = svdOfM.matrixU();
00464 const Eigen::MatrixXd V = svdOfM.matrixV();
00465 const Eigen::VectorXd S = svdOfM.singularValues();
00466 Eigen::VectorXd Sinv = S;
00467
00468 double maxsv = 0;
00469 for (std::size_t i = 0; i < S.rows(); ++i)
00470 {
00471 if (fabs(S(i)) > maxsv)
00472 {
00473 maxsv = fabs(S(i));
00474 }
00475 }
00476
00477 for (std::size_t i = 0; i < S.rows(); ++i)
00478 {
00479 Sinv(i) = ((S(i)< 0.0001)?0:1/S(i));
00480 }
00481
00482 matrix_inv = V * Sinv.asDiagonal() * U.transpose();
00483 }
00484
00485 void OutputRecorder::euler(std::vector<double>* out, double in, double dt)
00486 {
00487 if (out->size() == 0)
00488 {
00489 out->push_back(in*dt);
00490 }
00491 else
00492 {
00493 out->push_back(out->at(out->size()-1) + in*dt);
00494 }
00495 }
00496
00497 void OutputRecorder::fillDataVectors(double x_dot_lin_in, double x_dot_lin_out,
00498 double y_dot_lin_in, double y_dot_lin_out,
00499 double z_dot_lin_in, double z_dot_lin_out,
00500 double x_dot_rot_in, double x_dot_rot_out,
00501 double y_dot_rot_in, double y_dot_rot_out,
00502 double z_dot_rot_in, double z_dot_rot_out,
00503 double x_lin_out, double y_lin_out, double z_lin_out, double x_rot_out, double y_rot_out, double z_rot_out)
00504 {
00506 x_dot_lin_vec_in_.push_back(x_dot_lin_in);
00507 x_dot_lin_vec_out_.push_back(x_dot_lin_out);
00508 y_dot_lin_vec_in_.push_back(y_dot_lin_in);
00509 y_dot_lin_vec_out_.push_back(y_dot_lin_out);
00510 z_dot_lin_vec_in_.push_back(z_dot_lin_in);
00511 z_dot_lin_vec_out_.push_back(z_dot_lin_out);
00512
00514 x_dot_rot_vec_in_.push_back(x_dot_rot_in);
00515 x_dot_rot_vec_out_.push_back(x_dot_rot_out);
00516 y_dot_rot_vec_in_.push_back(y_dot_rot_in);
00517 y_dot_rot_vec_out_.push_back(y_dot_rot_out);
00518 z_dot_rot_vec_in_.push_back(z_dot_rot_in);
00519 z_dot_rot_vec_out_.push_back(z_dot_rot_out);
00520
00522 x_lin_vec_out_.push_back(x_lin_out);
00523 y_lin_vec_out_.push_back(y_lin_out);
00524 z_lin_vec_out_.push_back(z_lin_out);
00525
00527 x_rot_vec_out_.push_back(x_rot_out);
00528 y_rot_vec_out_.push_back(y_rot_out);
00529 z_rot_vec_out_.push_back(z_rot_out);
00530 }
00531
00532 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)
00533 {
00534 std::ofstream myfile;
00535 std::string name;
00536
00537 name = output_file_path_ + file_name + ".m";
00538 ROS_INFO("Writing results to: %s", name.c_str());
00539 const char* charPath = name.c_str();
00540
00541 myfile.open(charPath);
00542 myfile << "clear all;close all;\n\n";
00543
00545 myfile << file_name << "_in = [" << std::endl;
00546 for (int i = 0; i < in->size()-1; i++)
00547 {
00548 myfile << in->at(i) <<std::endl;
00549 }
00550 myfile << "]; \n" << std::endl;
00551
00552 myfile << file_name << "_x_lin_out = [" << std::endl;
00553 for (int i = 0; i < x_lin_out->size()-1; i++)
00554 {
00555 myfile << x_lin_out->at(i) <<std::endl;
00556 }
00557 myfile << "]; \n" << std::endl;
00558
00559 myfile << file_name << "_y_lin_out = [" << std::endl;
00560 for (int i = 0; i < y_lin_out->size()-1; i++)
00561 {
00562 myfile << y_lin_out->at(i) <<std::endl;
00563 }
00564 myfile << "]; \n" << std::endl;
00565
00566 myfile << file_name << "_z_lin_out = [" << std::endl;
00567 for (int i = 0; i < z_lin_out->size()-1; i++)
00568 {
00569 myfile << z_lin_out->at(i) <<std::endl;
00570 }
00571 myfile << "]; \n" << std::endl;
00572
00573 myfile << file_name << "_x_rot_out = [" << std::endl;
00574 for (int i = 0; i < x_rot_out->size()-1; i++)
00575 {
00576 myfile << x_rot_out->at(i) <<std::endl;
00577 }
00578 myfile << "]; \n" << std::endl;
00579
00580 myfile << file_name << "_y_rot_out = [" << std::endl;
00581 for (int i = 0; i < y_rot_out->size()-1; i++)
00582 {
00583 myfile << y_rot_out->at(i) <<std::endl;
00584 }
00585 myfile << "]; \n" << std::endl;
00586
00587 myfile << file_name << "_z_rot_out = [" << std::endl;
00588 for (int i = 0; i < z_rot_out->size()-1; i++)
00589 {
00590 myfile << z_rot_out->at(i) <<std::endl;
00591 }
00592 myfile << "]; \n" << std::endl;
00593
00594 myfile << "k = size(" <<file_name << "_in);" << std::endl;
00595 myfile << "t = linspace(0,k(1)*" << fabs(dt_) << ",size(" <<file_name << "_in));" << std::endl;
00596
00597 myfile << "figure" << std::endl;
00598 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;
00599 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;
00600 myfile << "grid" << std::endl;
00601
00602 myfile.close();
00603 }
00604
00605
00606 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)
00607 {
00608 std::ofstream myfile;
00609 std::string name;
00610 std::vector <double> errVec;
00611 double a1, a2, a3, b1, b2, b3 = 0.0;
00612 std::ostringstream a1_str, a2_str, a3_str, b1_str, b2_str, b3_str;
00613
00614 name = output_file_path_ + file_name + ".m";
00615 ROS_INFO("Writing results to: %s", name.c_str());
00616 const char* charPath = name.c_str();
00617
00618 myfile.open(charPath);
00619
00620 myfile << "clear all;close all;\n\n";
00621
00623 myfile << file_name << "_dot_in = [" << std::endl;
00624 for (int i = 0; i < dot_in->size()-1; i++)
00625 {
00626 myfile << dot_in->at(i) <<std::endl;
00627 }
00628 myfile << "]; \n" << std::endl;
00629
00630 myfile << file_name << "_dot_out = [" << std::endl;
00631 for (int i = 0; i < dot_out->size()-1; i++)
00632 {
00633 myfile << dot_out->at(i) <<std::endl;
00634 }
00635 myfile << "]; \n" << std::endl;
00636
00637 myfile << file_name << "_pos_out = [" << std::endl;
00638 for (int i = 0; i < pos_out->size()-1; i++)
00639 {
00640 myfile << pos_out->at(i) <<std::endl;
00641 }
00642 myfile << "]; \n" << std::endl;
00643
00644 myfile << file_name << "_dot_integrated = [" << std::endl;
00645 for (int i=0; i < dot_integrated->size()-1; i++)
00646 {
00647 myfile << dot_integrated->at(i) <<std::endl;
00648 }
00649 myfile << "]; \n" << std::endl;
00650
00651 myfile << "t = [" << std::endl;
00652 for (int i = 0; i < time_vec_.size()-1; i++)
00653 {
00654 myfile << time_vec_.at(i) <<std::endl;
00655 }
00656 myfile << "]; \n" << std::endl;
00658
00660 myfile << "k = size(" <<file_name << "_dot_in);" << std::endl;
00661 myfile << "t = linspace(0,k(1)*" << fabs(dt_) << ",size(" <<file_name << "_dot_in));" << std::endl;
00663
00665 myfile << "s = tf('s'); z=tf('z',1/50);" << std::endl;
00666
00667 errVec.clear();
00668
00670 a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
00671 a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
00672
00673 errVec.push_back(calculateLS(dot_out, dot_in, 1, a1, a2, a3, b1, b2, b3));
00674
00675 a1_str << a1;
00676 b1_str << b1;
00677
00678 std::string Gz1 = "Gz_" + file_name + "1=" + b1_str.str() + "*z^-1/(1" + a1_str.str() + "*z^-1);";
00679 while (Gz1.find("+-") != std::string::npos)
00680 {
00681 Gz1.replace(Gz1.find("+-"), 2, "-");
00682 }
00683
00684 myfile << Gz1;
00685
00687 a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
00688 a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
00689
00690 errVec.push_back(calculateLS(dot_out, dot_in, 2, a1, a2, a3, b1, b2, b3));
00691
00692 a1_str << a1;
00693 a2_str << a2;
00694
00695 b1_str << b1;
00696 b2_str << b2;
00697
00698
00699 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);";
00700 while (Gz2.find("+-") != std::string::npos)
00701 {
00702 Gz2.replace(Gz2.find("+-"), 2, "-");
00703 }
00704
00705 myfile << Gz2;
00706
00707
00709 a1_str.str(""); a2_str.str(""); a3_str.str(""); b1_str.str(""); b2_str.str(""); b3_str.str("");
00710 a1_str.clear(); a2_str.clear(); a3_str.clear(); b1_str.clear(); b2_str.clear(); b3_str.clear();
00711
00712 errVec.push_back(calculateLS(dot_out, dot_in, 3, a1, a2, a3, b1, b2, b3));
00713
00714 a1_str << a1;
00715 a2_str << a2;
00716 a3_str << a3;
00717 b1_str << b1;
00718 b2_str << b2;
00719 b3_str << b3;
00720
00721 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);";
00722 while (Gz3.find("+-") != std::string::npos)
00723 {
00724 Gz3.replace(Gz3.find("+-"), 2, "-");
00725 }
00726 myfile << Gz3;
00727
00728
00730 myfile << "e =[" << errVec.at(0) << "," << errVec.at(1) << "," << errVec.at(2) << "];" << std::endl;
00731 myfile << "figure; semilogy(e); grid;" << std::endl;
00732
00733 double step = 0.0;
00734 for (int i = 0; i < dot_in->size()-1; i++)
00735 {
00736 step+=dot_in->at(i);
00737 }
00738 step/=(dot_in->size()-1);
00739 std::cout << "step = " << step <<std::endl;
00740
00741 int length = static_cast<int>(pos_out->size()*2/3) - static_cast<int>(pos_out->size()/3);
00742 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;
00743
00744 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);
00745
00747 myfile << "Gz_" << file_name << "1 = minreal(Gz_" << file_name << "1);" << std::endl;
00748 myfile << "Gs_" << file_name << "1=d2c(Gz_" << file_name << "1,'matched');" << std::endl;
00749
00750 myfile << "Gs_" << file_name << "_integrated1 = Gs_" << file_name << "1* (1/s);" << std::endl;
00751 myfile << "Gs_" << file_name << "_out1 = lsim(Gs_" << file_name << "1," << file_name << "_dot_in,t);" << std::endl;
00752 myfile << "Gs_" << file_name << "_out_integrated1 = lsim(Gs_" << file_name << "_integrated1," << file_name << "_dot_in,t);" << std::endl;
00753
00754
00755 myfile << "figure" << std::endl;
00756 myfile << "subplot(2,1,1);" << std::endl;
00757 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out1)" << std::endl;
00758 myfile << "c=legend('Velocity Input','Velocity Systemresponse','PT1 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00759 myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
00760 myfile << "grid" << std::endl;
00761 myfile << "subplot(2,1,2);" << std::endl;
00762 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated1)" << std::endl;
00763 myfile << "c=legend('Velocity Input','Position Systemresponse','IT1 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00764 myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
00765 myfile << "grid" << std::endl;
00766
00768 myfile << "Gz_" << file_name << "2 = minreal(Gz_" << file_name << "2);"<< std::endl;
00769 myfile << "Gs_" << file_name << "2=d2c(Gz_" << file_name << "2,'matched');" << std::endl;
00770
00771 myfile << "Gs_" << file_name << "_integrated2 = Gs_" << file_name << "2*(1/s);" << std::endl;
00772 myfile << "Gs_" << file_name << "_out2 = lsim(Gs_" << file_name << "2," << file_name << "_dot_in,t);" << std::endl;
00773 myfile << "Gs_" << file_name << "_out_integrated2 = lsim(Gs_" << file_name << "_integrated2," << file_name << "_dot_in,t);" << std::endl;
00774
00775
00776 myfile << "figure" << std::endl;
00777 myfile << "subplot(2,1,1);" << std::endl;
00778 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out2)" << std::endl;
00779 myfile << "c=legend('Velocity Input','Velocity Systemresponse','PDT2 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00780 myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
00781 myfile << "grid" << std::endl;
00782 myfile << "subplot(2,1,2);" << std::endl;
00783 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated2)" << std::endl;
00784 myfile << "c=legend('Velocity Input','Position Systemresponse','PIDT2 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00785 myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
00786 myfile << "grid" << std::endl;
00787
00789 myfile << "Gz_" << file_name << "3 = minreal(Gz_" << file_name << "3);" << std::endl;
00790 myfile << "Gs_" << file_name << "3=d2c(Gz_" << file_name << "3,'matched');" << std::endl;
00791
00792 myfile << "Gs_" << file_name << "_integrated3 = Gs_" << file_name << "3*(1/s);" << std::endl;
00793 myfile << "Gs_" << file_name << "_out3 = lsim(Gs_" << file_name << "3," << file_name << "_dot_in,t);" << std::endl;
00794 myfile << "Gs_" << file_name << "_out_integrated3 = lsim(Gs_" << file_name << "_integrated3," << file_name << "_dot_in,t);" << std::endl;
00795
00796
00797 myfile << "figure" << std::endl;
00798 myfile << "subplot(2,1,1);" << std::endl;
00799 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_out,t,Gs_" << file_name << "_out3)" << std::endl;
00800 myfile << "c=legend('Velocity Input','Velocity Systemresponse','PD2T3 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00801 myfile << "title('" << file_name << " Velocity Stepresponse','interpreter','none')" << std::endl;
00802 myfile << "grid" << std::endl;
00803 myfile << "subplot(2,1,2);" << std::endl;
00804 myfile << "plot(t," << file_name << "_dot_in,t," << file_name << "_dot_integrated,t,Gs_" << file_name << "_out_integrated3)" << std::endl;
00805 myfile << "c=legend('Velocity Input','Position Systemresponse','PID2T3 Modelresponse','Location','NorthEastOutside'); \n set(c,'Interpreter','none');" << std::endl;
00806 myfile << "title('" << file_name << " Position Stepresponse','interpreter','none')" << std::endl;
00807 myfile << "grid" << std::endl;
00808
00809 myfile.close();
00810 }
00811