//! old task angle position controller void ChainTask::doControl() { Rotation desired = Rotation::RPY(desired_values[3],desired_values[4],desired_values[5]); Rotation measured = Rotation::RPY(chi_f_spatula(0),chi_f_spatula(1),chi_f_spatula(2)); Vector rot = diff(desired,measured); rot = measured.Inverse()*rot; for(unsigned int i=0;i<NC;i++) { if(i<N_CHIF_BAKER || new_rotation) ydot(i)=feedback_gain[i]*(desired_values[i] - chi_f(i)); else ydot(i)=feedback_gain[i]*rot(i-N_CHIF_BAKER); } }
void FramesTest::TestRotation2(const Vector& v,double a,double b,double c) { Vector v2; // Wrench Wrench w(Vector(7,-1,3),Vector(2,-3,3)); Twist t(Vector(6,3,5),Vector(4,-2,7)); // Rotation Rotation R; Rotation R2; double ra; double rb; double rc; R = Rotation::RPY(a,b,c); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitX(),R.UnitX()),1.0,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitY(),R.UnitY()),1.0,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitZ(),R.UnitZ()),1.0,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitX(),R.UnitY()),0.0,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitX(),R.UnitZ()),0.0,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(dot(R.UnitY(),R.UnitZ()),0.0,epsilon); R2=R; CPPUNIT_ASSERT_EQUAL(R,R2); CPPUNIT_ASSERT_DOUBLES_EQUAL((R*v).Norm(),v.Norm(),epsilon); CPPUNIT_ASSERT_EQUAL(R.Inverse(R*v),v); CPPUNIT_ASSERT_EQUAL(R.Inverse(R*t),t); CPPUNIT_ASSERT_EQUAL(R.Inverse(R*w),w); CPPUNIT_ASSERT_EQUAL(R*R.Inverse(v),v); CPPUNIT_ASSERT_EQUAL(R*Rotation::Identity(),R); CPPUNIT_ASSERT_EQUAL(Rotation::Identity()*R,R); CPPUNIT_ASSERT_EQUAL(R*(R*(R*v)),(R*R*R)*v); CPPUNIT_ASSERT_EQUAL(R*(R*(R*t)),(R*R*R)*t); CPPUNIT_ASSERT_EQUAL(R*(R*(R*w)),(R*R*R)*w); CPPUNIT_ASSERT_EQUAL(R*R.Inverse(),Rotation::Identity()); CPPUNIT_ASSERT_EQUAL(R.Inverse()*R,Rotation::Identity()); CPPUNIT_ASSERT_EQUAL(R.Inverse()*v,R.Inverse(v)); R.GetRPY(ra,rb,rc); CPPUNIT_ASSERT_DOUBLES_EQUAL(ra,a,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rb,b,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rc,c,epsilon); R = Rotation::EulerZYX(a,b,c); R.GetEulerZYX(ra,rb,rc); CPPUNIT_ASSERT_DOUBLES_EQUAL(ra,a,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rb,b,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rc,c,epsilon); R = Rotation::EulerZYZ(a,b,c); R.GetEulerZYZ(ra,rb,rc); CPPUNIT_ASSERT_DOUBLES_EQUAL(ra,a,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rb,b,epsilon); CPPUNIT_ASSERT_DOUBLES_EQUAL(rc,c,epsilon); double angle= R.GetRotAngle(v2); R2=Rotation::Rot2(v2,angle); CPPUNIT_ASSERT_EQUAL(R2,R); R2=Rotation::Rot(v2*1E20,angle); CPPUNIT_ASSERT_EQUAL(R,R2); v2=Vector(6,2,4); CPPUNIT_ASSERT_DOUBLES_EQUAL((v2).Norm(),::sqrt(dot(v2,v2)),epsilon); }
void JacobianTest::TestChangeBase(){ //Create a random jacobian Jacobian j1(5); j1.data.setRandom(); //Create a random rotation Rotation r; random(r); Jacobian j2(5); CPPUNIT_ASSERT(changeBase(j1,r,j2)); CPPUNIT_ASSERT(j1!=j2); Jacobian j3(4); CPPUNIT_ASSERT(!changeBase(j1,r,j3)); j3.resize(5); CPPUNIT_ASSERT(changeBase(j2,r.Inverse(),j3)); CPPUNIT_ASSERT_EQUAL(j1,j3); }
//! new range-controller. //! this controller accepts ranges of accepted positions and //! lowers the weight to zero when inside that range. void ChainTask::doControl_ranges() { /// HACK FOR THE RPY ANGLES, PART 1 double middle[3], margin[3]; for(int i=0; i < 3; i++) { double lo = ros_constraint_command.pos_lo[i+3]; double hi = ros_constraint_command.pos_hi[i+3]; middle[i] = (hi + lo)/2.0; margin[i] = (hi - lo)/2.0; } Rotation desired = Rotation::RPY(middle[0], middle[1], middle[2]); Rotation measured = Rotation::RPY(chi_f_spatula(0), chi_f_spatula(1), chi_f_spatula(2)); Vector rot = diff(desired, measured); rot = measured.Inverse()*rot; /// /// double s = 0.05; for(int i=0; i < 6; i++) { if(ros_constraint_command.weight[i] == 0.0) { ydot(i) = 0.0; continue; } double value = chi_f(i); double lo = ros_constraint_command.pos_lo[i]; double hi = ros_constraint_command.pos_hi[i]; if(i >= 3 && !new_rotation) /// HACK FOR THE RPY ANGLES, PART 2 { lo = value + rot(i-3) - margin[i-3]; hi = value + rot(i-3) + margin[i-3]; } /// /// // adjust margin if range is too small double ss = (hi - lo < 2*s) ? (hi - lo) / 2 : s; if(value > hi - ss) { ydot(i) = feedback_gain[i]*(hi - ss - value); desired_values[i] = hi - ss; } else if(value < lo + ss) { ydot(i) = feedback_gain[i]*(lo + ss - value); desired_values[i] = lo + ss; } else { ydot(i) = 0.0; desired_values[i] = value; } if(value > hi || value < lo) { weights[i] = 1.0; } else { double w_lo = (1/s)*(-hi + value)+1; double w_hi = (1/s)*( lo - value)+1; w_lo = (w_lo > 0.0) ? w_lo : 0.0; w_hi = (w_hi > 0.0) ? w_hi : 0.0; weights[i] = (w_lo > w_hi) ? w_lo : w_hi; } } }
Rotation Inverse(const Rotation& rot){ return rot.Inverse(); }
Rotation operator()(const Rotation& rot ) const { return rot.Inverse(); }