34 m_start_solver(false),
39 m_iteration_overflow(false),
40 m_apply_joint_coupling(false),
41 m_rolling_joint_present(false),
42 m_check_joint_limit_jacobian(false),
43 m_full_body_needed(false),
44 m_do_not_start_solver(false),
45 m_apply_weighted_solution(true),
47 m_wait_for_sync(false),
48 m_solver_pending(true),
49 m_thread_running(false),
50 m_apply_fault_tolerance(false)
65 srand ( (
uint)std::time(
nullptr) );
76 m_start_solver(false),
81 m_iteration_overflow(false),
82 m_apply_joint_coupling(false),
83 m_rolling_joint_present(false),
84 m_check_joint_limit_jacobian(false),
85 m_full_body_needed(false),
86 m_do_not_start_solver(true),
87 m_apply_weighted_solution(true),
89 m_wait_for_sync(false),
90 m_solver_pending(true),
91 m_thread_running(false),
92 m_apply_fault_tolerance(false)
160 std::ofstream output_file;
161 output_file.open(filename);
162 if (!output_file.is_open())
163 throw std::runtime_error(
"Cannot open File " + filename);
167 output_file <<
"m_robot_frame_T, ";
172 output_file << std::endl;
174 output_file <<
"m_tool_frame_T, ";
179 output_file << std::endl;
181 output_file <<
"#id, a, alpha, d, theta, min, max, type" << std::endl;
182 for (
size_t i = 0; i <
m_DH_table.size(); i++)
184 output_file << i <<
", "
203 throw std::runtime_error(
"Cannot open File " + filename);
206 bool dh_convention_set =
false;
211 std::getline(file, text,
'\n');
220 std::vector<std::string> results =
split(text,
',',
true);
222 if (results[0][0] ==
'#')
225 if (results[0] ==
"m_robot_frame_T")
227 for (
size_t i = 0; i < 16; i++)
234 else if (results[0] ==
"m_tool_frame_T")
236 for (
size_t i = 0; i < 16; i++)
241 else if (results[0] ==
"DH")
243 int dh_i = std::stoi(results[1]);
246 dh_convention_set =
true;
250 if (!dh_convention_set)
251 throw std::runtime_error(
"First entry shall be the dh convention");
254 double a = std::stod(results[pos++]);
255 double alpha = std::stod(results[pos++]);
256 double d = std::stod(results[pos++]);
257 double theta = std::stod(results[pos++]);
258 double min = std::stod(results[pos++]);
259 double max = std::stod(results[pos++]);
260 int jt_i = std::stoi(results[pos++]);
283 void Endorob::add_DH_entry(
const double &a,
const double &alpha,
const double &d,
const double &theta,
const Joint_type &type,
const double &a_bis,
const double &theta_bis,
const uint &flex)
297 for(
unsigned i = 0; i < flex-1; i++)
325 m_DH_table[current_index].set_joint_limits(min/2, max/2);
326 m_DH_table[current_index-1].set_joint_limits(min/2, max/2);
329 m_DH_table[current_index].set_joint_limits(min, max);
373 std::cout <<
"Error: No DH table...\n";
483 std::cout <<
"waiting ";
505 std::cout <<
"OOOOOOOOOOO____FAILED PROCESSOR ASSIGNMENT____OOOOOOOOOOO" << std::endl;
506 std::cout <<
"...NOW RUNNING ON DEFAULT CPU..." << std::endl;
519 int rc = pthread_setaffinity_np(
psolver->native_handle(),
sizeof(cpu_set_t), &cpuset);
528 std::cout <<
"OOOOOOOOOOO____FAILED PROCESSOR ASSIGNMENT____OOOOOOOOOOO" << std::endl;
529 std::cout <<
"...NOW RUNNING ON DEFAULT CPU..." << std::endl;
574 for(
int i = 0; i < q.rows(); i++)
577 double joint_offset = 0;
612 for(
int i = 0; i < tmp_q_vec.rows(); i++)
615 double joint_offset = 0;
683 for(
unsigned i = 0; i < 6; i++)
714 for(
unsigned i = 0; i < coupling.rows(); i++)
735 std::cout <<
"initial coupling\n" << coupling << std::endl;
777 double joint_offset = 0.0;
813 for(
int i = 0; i <
m_q_vec.rows(); i++)
816 double joint_offset = 0.0;
869 for(
llong i = 0; i < q.rows(); i++)
872 double joint_offset = 0.0;
899 fwd_k_vec.block<4,4>(i*4,0) = T_mat;
908 for(
int i = 0; i < q.rows(); i++)
911 double joint_offset = 0.0;
937 fwd_k_vec.block<4,4>(i*4,0) = T_mat;
944 fwd_k_vec.block<4,4>(
m_joints*4,0) = T_mat;
959 return m_tip_T.block<3,1>(0,3);
984 for(
unsigned i = 0; i <
m_joints; i++)
1027 m_J_rot.block<3,1>(0,i) << 0,0,0;
1037 m_J_vel.block<3,1>(0,i) << 0,0,0;
1038 m_J_rot.block<3,1>(0,i) << 0,0,0;
1045 m_J_vel.block<3,1>(0,i) << 0,0,0;
1046 m_J_rot.block<3,1>(0,i) << 0,0,0;
1083 unsigned joint_index;
1089 for(
unsigned j = 0; j <
m_joints; j++)
1109 for(
unsigned i = 0; i < joint_index; i++)
1135 m_J_rot.block<3,1>(0,i) << 0,0,0;
1180 unsigned joint_index;
1212 for(
unsigned i = 0; i < joint_index; i++)
1232 m_J_rot.block<3,1>(0,i) << 0,0,0;
1240 m_J_vel.block<3,1>(0,i) << 0,0,0;
1241 m_J_rot.block<3,1>(0,i) << 0,0,0;
1282 Vec3d error = Td.block<3,1>(0,3) - Te.block<3,1>(0,3);
1295 Mat3d R = Td.block<3,3>(0,0) * Te.block<3,3>(0,0).transpose();
1297 Eigen::AngleAxisd angle_axis(R);
1299 result = angle_axis.axis() * sin(angle_axis.angle());
1336 auto vec_size =
m_error.rows() - 3;
1367 std::cout <<
"Solver problem...\n";
1607 std::cout <<
"Solver problem...\n";
1681 int fault_LUT[54]={0,0,0,0,0,0,6,6,7,7,6,6,7,7,8,8,9,9,8,8,9,9,10,10,11,11,10,10,11,11,12,12,13,13,12,12,13,13,14,14,15,15,14,14,15,15,16,16,17,17,16,16,17,17};
1684 for(
auto l = 0; l < 54; l++)
1761 std::cout <<
"Solver exited...\n";
1898 std::this_thread::sleep_for(std::chrono::microseconds(1));
1947 result.resize(
m_dof);
1949 for(
unsigned i = 0; i <
m_dof; i++)
1951 int val = rand() % 1000;
1953 double min =
m_DH_table[i].joint_limit_min();
1954 double max =
m_DH_table[i].joint_limit_max();
1955 result[i] = ((1 - (double)val/1000) * min) + ((
double)val/1000 * max);
1970 rot = mat.block<3,3>(0,0);
1975 result = rot.eulerAngles(2,1,0);
1983 T.block<3,3>(0,0) = (Eigen::AngleAxisd(rpy[0], Vec3d::UnitZ())
1984 * Eigen::AngleAxisd(rpy[1], Vec3d::UnitY())
1985 * Eigen::AngleAxisd(rpy[2], Vec3d::UnitX())).toRotationMatrix();
1991 return Eigen::AngleAxisd(angle, Vec3d::UnitX()).toRotationMatrix();
1996 return Eigen::AngleAxisd(angle, Vec3d::UnitY()).toRotationMatrix();
2001 return Eigen::AngleAxisd(angle, Vec3d::UnitZ()).toRotationMatrix();
2006 return Eigen::AngleAxisd(angle, axis).toRotationMatrix();
2013 result.block<3,3>(0,0) = rot * result.block<3,3>(0,0);
2020 Mat4d rot4=Eigen::MatrixXd::Identity(4,4), result = T;
2022 rot4.block<3,3>(0,0) = rot;
2024 result.block<3,1>(0,3) = result.block<3,1>(0,3) - P;
2026 result = rot4 * result;
2028 result.block<3,1>(0,3) = result.block<3,1>(0,3) + P;
2035 Mat4d rot4 = Eigen::MatrixXd::Identity(4,4), result = T;
2038 rot4.block<3,3>(0,0) =
rot_xyz(angle, axis);;
2040 result.block<3,1>(0,3) = result.block<3,1>(0,3) - P;
2042 result = rot4 * result;
2044 result.block<3,1>(0,3) = result.block<3,1>(0,3) + P;
2056 result = A + (P-A).dot(B-A)/(B-A).dot(B-A)*(B-A);
2066 l = (B-A).normalized();
2068 double delta = pow(l.dot(A-center),2) - pow((A-center).norm(),2) + pow(radius,2);
2074 double d1 = - l.dot(A-center) + sqrt( delta );
2084 result = A + d1 * l;
2090 double d = - l.dot(A-center);
2132 for(
auto i = 0; i < A.rows(); i++)
2137 double res = sqrt( B.sum()/n );
2199 Vec result = desired_shape;
2202 int path_index = path.size() - 1;
2203 if(path.size() > desired_shape.rows()/3)
2206 int index_point = desired_shape.rows() - 6;
2212 for(
int i = desired_shape.rows()/3 - 2; i > 0 ; i--)
2217 Vec3d link_end = result.block<3,1>(index_point,0);
2220 Vec3d a = path[path_index-1];
2221 Vec3d b = path[path_index];
2236 double t = translation;
2239 t = translation / joint_L;
2241 Vec3d result_inter = a + t * (b - a);
2244 Vec3d tmp_link_start = result_inter;
2248 Vec3d v = tmp_link_start - link_end;
2251 Vec3d link_start = link_end + u;
2253 result.block<3,1>(index_point-3,0) = link_start;
2269 Vec result = desired_shape;
2270 int path_index = path.size() - 1;
2271 int index_point = desired_shape.rows() - 6;
2307 bool first_iteration =
true;
2308 for(
int i = desired_shape.rows()/3 - 2; i > 0 ; i--)
2311 Vec3d link_end = result.block<3,1>(index_point,0);
2314 Vec3d current_path_point = path[path_index];
2357 double dist1 = (link_end-current_path_point).norm();
2360 while((dist1 < link_length) && (path_index > 0))
2366 current_path_point = path[path_index];
2369 dist1 = (link_end-current_path_point).norm();
2371 first_iteration =
false;
2377 Vec3d prev_path_point;
2381 if((path_index == (path.size()-1)) && first_iteration)
2383 prev_path_point = link_end;
2384 first_iteration =
false;
2390 prev_path_point = path[path_index+1];
2399 double verif_length = (link_end - link_start).norm();
2400 double diff = abs(verif_length - link_length);
2404 std::cout <<
"PROBLEM WITH LINK LENGTH !!!!!!!!!!!!!!\n";
2457 result.block<3,1>(index_point-3,0) = link_start;
2506 Vec result = desired_shape;
2507 int path_index = path.
size() - 1;
2508 int index_point = desired_shape.rows() - 6;
2539 bool first_iteration =
true;
2540 for(
int i = desired_shape.rows()/3 - 2; i > 0 ; i--)
2544 Vec3d link_end = result.block<3,1>(index_point,0);
2548 Vec3d current_path_point = path[path_index];
2553 if(link_length == 0)
2557 if(link_length != 0)
2561 double dist1 = (link_end-current_path_point).norm();
2564 while((dist1 < link_length) && (path_index > 0))
2570 current_path_point = path[path_index];
2573 dist1 = (link_end-current_path_point).norm();
2575 first_iteration =
false;
2581 Vec3d prev_path_point;
2585 if((path_index == (path.
size()-1)) && first_iteration)
2587 prev_path_point = link_end;
2588 first_iteration =
false;
2594 prev_path_point = path[path_index+1];
2603 double verif_length = (link_end - link_start).norm();
2604 double diff = abs(verif_length - link_length);
2608 std::cout <<
"PROBLEM WITH LINK LENGTH !!!!!!!!!!!!!!\n";
2613 link_start = link_end;
2619 result.block<1,1>(index_point-3 + 1, 0) = link_start.block<1,1>(1,0);
2623 result.block<2,1>(index_point-3, 0) = link_start.block<2,1>(0,0);
2627 result.block<3,1>(index_point-3, 0) = link_start;
2677 int path_index = path.
size() - 1;
2678 int index_point = desired_shape.
rows() - 6;
2694 bool first_iteration =
true;
2695 for(
int i = desired_shape.
rows()/3 - 2; i > 0 ; i--)
2704 Vec3d current_path_point = path[path_index];
2709 if(link_length == 0)
2713 if(link_length != 0)
2717 double dist1 = (link_end-current_path_point).norm();
2720 while((dist1 < link_length) && (path_index > 0))
2726 current_path_point = path[path_index];
2729 dist1 = (link_end-current_path_point).norm();
2731 first_iteration =
false;
2737 Vec3d prev_path_point;
2741 if((path_index == (path.
size()-1)) && first_iteration)
2743 prev_path_point = link_end;
2744 first_iteration =
false;
2750 prev_path_point = path[path_index+1];
2758 static bool skip_next =
false;
2781 double verif_length = (link_end - link_start).norm();
2782 double diff = abs(verif_length - link_length);
2786 std::cout <<
"PROBLEM WITH LINK LENGTH !!!!!!!!!!!!!!\n";
2791 link_start = link_end;
2798 result.
set(index_point-3 + 1, 0, 1, 1, link_start.block<1,1>(1,0));
2804 result.
set(index_point-3, 0, 2, 1, link_start.block<2,1>(0,0));
2809 result.
set(index_point-3, 0, 3, 1, link_start);
2833 Vec3d base = vec.block<3,1>(0,0);
2836 for(
unsigned i = 0; i < vec.rows(); i+=3)
2838 result.block<3,1>(i,0) = vec.block<3,1>(i,0) - base;
2879 for(
int i = index * 3; i < index * 3 + 3 ; i++)
2921 for(
unsigned i = 0; i < q_vec.rows(); i++)
2926 double x = fmod(result[i] +
M_PI, 2*
M_PI);
2929 result[i] = x -
M_PI;
2948 for(
unsigned i = 0; i < 6; i++)
2953 result.row(index) << mat.row(i);
3001 double prev_val = -1;
3021 double dof_val = -1;
3036 std::vector<std::string>
Endorob::split(
const std::string & s,
char delimiter,
bool remove_empty)
3038 std::vector<std::string> tokens;
3040 std::istringstream tokenStream(s);
3041 while (std::getline(tokenStream, token, delimiter))
3043 if (remove_empty && token ==
"")
3045 tokens.push_back(token);
3052 bool result =
false;
3057 for(
unsigned i = 0; i < q.rows(); i++)
3062 else if(q[i] <
m_DH_table[i].joint_limit_min())
3069 for(
unsigned i = 0; i < q.rows(); i++)
3088 double prev_val = -1;
3090 for(
unsigned i = 0; i <
m_joints; i++)
3104 for(
unsigned i = 0; i <
m_joints-1; i++)
3118 for(
unsigned i = 0; i <
m_joints-1; i++)
3120 body_vec.block<3,1>(cpt_index,0) = fwd_k.block<3,1>(i*4,3);
3125 body_vec.block<3,1>(cpt_index,0) = fwd_k.block<3,1>(
m_joints*4,3);
3138 for(
unsigned i = 0; i <
m_joints; i++)
3235 std::cout <<
"Endorob found: " <<
m_CPU_amount <<
" CPUs on your machine." << std::endl << std::endl;
3237 std::cout <<
"Endorob found only " <<
m_CPU_amount <<
" CPU on your machine." << std::endl << std::endl;
3243 std::this_thread::sleep_for(std::chrono::milliseconds(100));
3249 for(
unsigned i = 0; i <
m_error.rows()-9; i++)
3280 for(
unsigned i = 0; i < q_vec.rows(); i++)
3282 if(abs(result[i]) < val)
3294 double a = DH.
a(), alpha = DH.
alpha(), d = DH.
d(), theta = DH.
theta();
3315 mat << cos(theta), -sin(theta), 0, a,
3316 sin(theta)*cos(alpha), cos(theta)*cos(alpha), -sin(alpha), -sin(alpha)*d,
3317 sin(theta)*sin(alpha), cos(theta)*sin(alpha), cos(alpha), cos(alpha)*d,
3323 mat << cos(theta), -sin(theta)*cos(alpha), sin(theta)*sin(alpha), a*cos(theta),
3324 sin(theta), cos(theta)*cos(alpha), -cos(theta)*sin(alpha), a*sin(theta),
3325 0, sin(alpha), cos(alpha), d,
3341 double tolerance = 1.E-6;
3344 Eigen::JacobiSVD<Mat> svd(
m_J, Eigen::ComputeThinU | Eigen::ComputeThinV);
3347 Mat singular_values = svd.singularValues();
3348 Mat inv_singular_values = singular_values;
3351 unsigned int cpt_zero = 0;
3352 for(
int i = 0; i < singular_values.rows(); i++)
3354 if(singular_values(i) > tolerance)
3356 inv_singular_values(i) = 1.0/singular_values(i);
3360 inv_singular_values(i) = 0;
3366 Mat Umat, Vmat, newU, newV, newinv;
3367 Umat = svd.matrixU();
3368 Vmat = svd.matrixV();
3370 newV = Vmat.block(0, 0, Vmat.rows(), Vmat.cols()-cpt_zero);
3371 newU = Umat.block(0, 0, Umat.rows(), Umat.cols()-cpt_zero);
3372 newinv = inv_singular_values.block(0, 0, (inv_singular_values.rows()-cpt_zero), 1);
3376 m_J_inv = newV * newinv.asDiagonal() * newU.transpose();
3390 double tolerance = 1.E-15;
3393 Eigen::JacobiSVD<Mat> svd(
m_J_masked, Eigen::ComputeThinU | Eigen::ComputeThinV);
3396 Mat singular_values = svd.singularValues();
3397 Mat inv_singular_values = singular_values;
3400 unsigned int cpt_zero = 0;
3401 for(
int i = 0; i < singular_values.rows(); i++)
3403 if(singular_values(i) > tolerance)
3405 inv_singular_values(i) = 1.0/singular_values(i);
3409 inv_singular_values(i) = 0;
3415 Mat Umat, Vmat, newU, newV, newinv;
3416 Umat = svd.matrixU();
3417 Vmat = svd.matrixV();
3419 newV = Vmat.block(0, 0, Vmat.rows(), Vmat.cols()-cpt_zero);
3420 newU = Umat.block(0, 0, Umat.rows(), Umat.cols()-cpt_zero);
3421 newinv = inv_singular_values.block(0, 0, (inv_singular_values.rows()-cpt_zero), 1);
3434 Eigen::JacobiSVD<Mat> svd(
m_J, Eigen::ComputeThinU | Eigen::ComputeThinV);
3437 Mat singular_values = svd.singularValues();
3441 Mat E = singular_values.asDiagonal();
3443 for(
int i = 0; i < singular_values.rows(); i++)
3447 E(i,i) = singular_values(i) / ( pow(singular_values(i),2) + pow(
m_lambda,2) );
3460 m_J_inv = svd.matrixV() * E * svd.matrixU().transpose();
3571 m_overwrite_file_period(false),
3572 m_header_written(false),
3574 m_start_loop(false),
3588 m_mode = Motion_mode::Idle;
3597 m_overwrite_file_period(false),
3598 m_header_written(false),
3600 m_start_loop(false),
3614 m_mode = Motion_mode::Idle;
3641 std::cout <<
"Motion RW stopped...\n";
3670 if(file_checker.good())
3674 int filenbr = std::stoi(filenumber);
3686 std::cout <<
"ERROR opening output file, check that file is not in use...\n";
3693 m_mode = Motion_mode::Write;
3704 std::cout <<
"\nRecording stopped.\n";
3727 std::cout <<
"ERROR opening input file, check that file exist and is not in use...\n";
3762 for(
unsigned r = 0; r < 4; r++)
3764 for(
unsigned c = 0; c < 4; c++)
3767 tmp_mat(r,c) = tmp_val;
3799 std::cout <<
"File read error, the file is not compatible with your robot...\n";
3804 std::cout <<
"\nReading done... Size: " <<
m_q_data.size() << std::endl;
3808 static long int cpt_delete = 0;
3809 for(
long unsigned int i = 0; i <
m_q_data.size()-1; i++)
3814 if(tmp_q == tmp_q_next)
3837 std::cout << cpt_delete;
3840 long unsigned int sz =
m_q_data.size();
3842 for(
long int i = sz-2; i >= 0; i--)
3862 m_mode = Motion_mode::Read;
3875 std::cout <<
"ERROR opening input file, check that file exist and is not in use...\n";
3912 for(
auto i = 0; i < qsize; i++)
3924 Mat4d tmptip = Mat4d::Identity();
3925 for(
auto c = 0; c < 4; c++)
3927 for(
auto r = 0; r < 3; r++)
3930 tmptip(r,c) = tmp_val;
3957 m_mode = Motion_mode::Read;
3969 std::cout <<
"ERROR opening input file, check that file exist and is not in use...\n";
4006 for(
auto i = 0; i < qsize; i++)
4018 Mat4d tmptip = Mat4d::Identity();
4019 for(
auto c = 0; c < 4; c++)
4021 for(
auto r = 0; r < 3; r++)
4024 tmptip(r,c) = tmp_val;
4051 m_mode = Motion_mode::Benchmark;
4069 m_mode = Motion_mode::Benchmark;
4075 static bool first_run =
true;
4078 auto now = chrono_time::now();
4087 if(file_checker.good())
4091 int filenbr = std::stoi(filenumber);
4103 std::cout <<
"ERROR opening output file, check that file is not in use...\n";
4118 for(
auto i = 0; i < curv.
rows(); i++)
4124 for(
auto c = 0; c < 4; c++)
4126 for(
auto r = 0; r < 3; r++)
4139 static bool first_run =
true;
4149 std::cout <<
"ERROR opening key stroke file, check that file is not in use...\n";
4163 bool result =
false;
4190 static bool first_run =
true;
4191 static double prev_time = 0.0;
4195 std::cout <<
"Motion RW started...\n";
4207 if(
m_mode == Motion_mode::Write ||
m_mode == Motion_mode::Read_Write)
4212 auto now = chrono_time::now();
4230 if(
m_mode == Motion_mode::Read ||
m_mode == Motion_mode::Read_Write)
4233 auto now = chrono_time::now();
4311 std::this_thread::sleep_for(std::chrono::seconds(2));
4313 static bool save_once_only =
true;
4316 save_once_only =
false;
4327 m_file_write.open(
"C:/Box Sync/Matlab/journal_paper/result_for_matlab_replay.csv", std::ios::out);
4330 std::cout <<
"ERROR opening output file, check that file is not in use...\n";
4336 m_file_write <<
"path, virtual, rob1, rob2, q, xi, error\n" ;
4347 for(
unsigned j = 0; j < 3; j++)
4350 if(i < rob.rows() / 3)
4364 if(qidx < xi.rows())
4386 std::cout <<
"Data output successfully" << std::endl;
4394 m_file_write.open(
"C:/Box Sync/Matlab/journal_paper/fault_result_for_matlab.csv", std::ios::out);
4397 std::cout <<
"ERROR opening output file, check that file is not in use...\n";
4403 m_file_write <<
"path, virtual, rob1, rob2, q, xi, error\n" ;
4422 for(
unsigned j = 0; j < 3; j++)
4425 if(i < rob.rows() / 3)
4439 if(qidx < xi.rows())
4461 std::cout <<
"Data output successfully" << std::endl;
4471 if(
m_mode == Motion_mode::Benchmark)
4488 auto now = chrono_time::now();
4529 for(
auto c = 0; c < 4; c++)
4531 for(
auto r = 0; r < 3; r++)
4553 std::cout <<
"Benchmark path finished\n";
4564 std::this_thread::sleep_for(std::chrono::microseconds(250));
4570 auto today = std::chrono::system_clock::now();
4571 std::time_t t = std::chrono::system_clock::to_time_t ( today );
4572 m_file_write <<
"# Endorob recorded motion: " << std::ctime(&t);
4579 for(
unsigned r = 0; r < 4; r++)
4580 for(
unsigned c = 0; c < 4; c++)
4583 for(
unsigned i = 0; i <
probot->
dof(); i++)
4598 for(
unsigned r = 0; r < 4; r++)
4600 for(
unsigned c = 0; c < 4; c++)
4606 for(
unsigned i = 0; i <
probot->
dof(); i++)
4655 result.resize(
size - 1);
4732 return m_curve.block<3,1>(0,0);
4754 for(
uint j = i*3; j < i*3 + 3; j++)
4764 for(
int i = index ; i < index + 3; i++)
4786 return m_curve.block<3,1>(index,0);
4791 m_curve.block(index1, index2, block1, block2) = val;
4797 return goal * start.transpose();
4807 Mat4d result = Mat4d::Identity(4,4);
4822 rot = mat.block<3,3>(0,0);
4827 result = rot.eulerAngles(0,1,2);
4835 result.block<3,3>(0,0) = mat.block<3,3>(0,0).transpose();
4836 result.block<3,1>(0,3) = - result.block<3,3>(0,0) * mat.block<3,1>(0,3);
4842 return val * 180 /
M_PI;
4847 return val *
M_PI / 180;
4852 return abs(a-b) <= tolerance;
4857 bool is_geq(
const double &a,
const double &b,
const double &tolerance)
4865 bool is_leq(
const double &a,
const double &b,
const double &tolerance)