output_recorder.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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     // JointNames
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     // OutputFilePath
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         // start_thread.join();
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     // get the console in raw mode
00228     tcgetattr(kfd, &cooked);
00229     memcpy(&raw, &cooked, sizeof(struct termios));
00230     raw.c_lflag &= ~(ICANON | ECHO);
00231     // Setting a new line, then end of file
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             // ROS_INFO("ist_vel: %f %f %f",twist.vel.x(), twist.vel.y(), twist.vel.z());
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     // Get transformation
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     // myfile << "Gs_" << file_name << "_integrated1 = Gs_" << file_name << "1*(" << Ki << "/s);" << std::endl;
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     // Plot
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     // myfile << "Gs_" << file_name << "_integrated2 = Gs_" << file_name << "2*(" << Ki << "/s);" << std::endl;
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     // Plot
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     // myfile << "Gs_" << file_name << "_integrated3 = Gs_" << file_name << "3*(" << Ki << "/s);" << std::endl;
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     // Plot
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 


cob_model_identifier
Author(s): Christoph Mark
autogenerated on Thu Jun 6 2019 21:19:11