00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Demotool.hpp"
00019 #include <bfl/wrappers/matrix/matrix_wrapper.h>
00020 #include <kdl/frames_io.hpp>
00021
00022 #define GRAVITY_CONSTANT 9.81
00023 #define MM_TO_M 0.001
00024
00025 namespace OCL
00026 {
00027 using namespace RTT;
00028 using namespace std;
00029 using namespace KDL;
00030 using namespace MatrixWrapper;
00031
00032
00033 Demotool::Demotool(string name, string propertyfile):
00034 TaskContext(name),
00035 _pos_leds_demotool("pos_leds_demotool","XYZ positions of all LED markers, relative to demtool frame"),
00036 _mass_demotool("mass_demotool","mass of objects attached to force censor of demotool"),
00037 _center_gravity_demotool("center_gravity_demotool","center of gravity of mass attached to demotool"),
00038 _gravity_dir_world("gravity_dir_world",""),
00039 _Frame_demotool_manip("demotool_manip","frame from demotool to manip"),
00040 _Frame_demotool_fs("demotool_fs","frame from demotool to force sensor"),
00041 _Frame_world_camera("world_camera","frame from world to camera"),
00042 _Wrench_fs_fs_port("WrenchData"),
00043 _Vector_led_camera_port("LedPositions"),
00044 _Wrench_world_world_port("wrench_world_world"),
00045 _Wrench_manip_manip_port("wrench_manip_manip"),
00046 _Twist_world_world_port("twit_world_world"),
00047 _Twist_world_manip_port("twist_world_manip"),
00048 _Frame_world_manip_port("frame_world_manip"),
00049 _num_visible_leds_port("num_visible_leds"),
00050 _calibrate_world_to_manip("calibrateWorldToManip", &Demotool::calibrateWorldToManip, this),
00051 _calibrate_wrench_sensor("calibrateWrenchSensor", &Demotool::calibrateWrenchSensor, this),
00052 _propertyfile(propertyfile)
00053 {
00054 log(Debug) <<this->getName()<<": adding Properties"<<endlog();
00055 properties()->addProperty(&_pos_leds_demotool);
00056 properties()->addProperty(&_mass_demotool);
00057 properties()->addProperty(&_center_gravity_demotool);
00058 properties()->addProperty(&_gravity_dir_world);
00059 properties()->addProperty(&_Frame_demotool_manip);
00060 properties()->addProperty(&_Frame_demotool_fs);
00061 properties()->addProperty(&_Frame_world_camera);
00062
00063 log(Debug) <<this->getName()<<": adding Ports"<<endlog();
00064 ports()->addPort(&_Wrench_fs_fs_port);
00065 ports()->addPort(&_Vector_led_camera_port);
00066 ports()->addPort(&_Wrench_world_world_port);
00067 ports()->addPort(&_Wrench_manip_manip_port);
00068 ports()->addPort(&_Twist_world_world_port);
00069 ports()->addPort(&_Twist_world_manip_port);
00070 ports()->addPort(&_Frame_world_manip_port);
00071 ports()->addPort(&_num_visible_leds_port);
00072
00073 log(Debug) <<this->getName()<<": adding Methods"<<endlog();
00074 methods()->addMethod(_calibrate_world_to_manip, "set world frame to current manip frame");
00075 methods()->addMethod(_calibrate_wrench_sensor, "set wrench sensor offset to measure zero force");
00076
00077 if (!marshalling()->readProperties(_propertyfile)) {
00078 log(Error) << "Failed to read the property file, continueing with default values." << endlog();
00079 }
00080
00081
00082 _Wrench_gravity_world_world.force = _gravity_dir_world.value() * (_mass_demotool.value() * GRAVITY_CONSTANT);
00083
00084
00085 _num_leds = (int) (_pos_leds_demotool.value().size()/3);
00086 assert( _pos_leds_demotool.value().size() == 3*_num_leds);
00087 _visible_leds.resize(_num_leds);
00088 _Vector_led_demotool.resize(_num_leds);
00089
00090
00091 Vector temp;
00092 for (unsigned int i=0; i<_num_leds; i++){
00093 for (unsigned int j=0; j<3; j++)
00094 temp(j) = _pos_leds_demotool.value()[(3*i)+j];
00095 _Vector_led_demotool[i] = temp;
00096 }
00097
00098 log(Debug) <<this->getName()<<": constructed."<<endlog();
00099 }
00100
00101 Demotool::~Demotool()
00102 {
00103 }
00104
00105
00106 bool Demotool::startup()
00107 {
00108
00109 TaskContext* wrench_sensor = getPeer("WrenchSensor");
00110 if (!wrench_sensor) log(Error) <<this->getName()<<": peer WrenchSensor not found."<<endlog();
00111
00112 _add_offset = wrench_sensor->commands()->getCommand<bool(Wrench)>("addOffset");
00113 if (!_add_offset.ready()) log(Error) <<this->getName()<<": command addOffset not found."<<endlog();
00114
00115
00116 SetToZero(_Twist_world_manip);
00117
00118
00119 _is_initialized = false;
00120
00121 return true;
00122 }
00123
00124
00125 void Demotool::update()
00126 {
00127
00128
00129 _num_visible_leds = 0;
00130 _Vector_led_camera = _Vector_led_camera_port.Get();
00131 assert(_Vector_led_camera.size() == _Vector_led_demotool.size());
00132 for (unsigned int i=0; i<_num_leds; i++){
00133 bool visible = true;
00134 for (unsigned int j=0; j<3; j++){
00135 double temp_double = _Vector_led_camera[i](j);
00136 if (temp_double == -99999 || temp_double == 0) visible = false;
00137 }
00138 _visible_leds[i] = visible;
00139 if (visible) _num_visible_leds++;
00140 }
00141
00142
00143
00144 if (_num_visible_leds >= 4){
00145 unsigned int pos = 0;
00146 Matrix matrix_leds_camera(3, _num_visible_leds);
00147 Matrix matrix_leds_demotool(4, _num_visible_leds);
00148 for (unsigned int i=0; i<_num_leds; i++){
00149 if (_visible_leds[i]){
00150 for (unsigned int j=0; j<3; j++){
00151 matrix_leds_camera (j+1, pos+1) = _Vector_led_camera [i](j) * MM_TO_M;
00152 matrix_leds_demotool(j+1, pos+1) = _Vector_led_demotool[i](j);
00153 }
00154 matrix_leds_demotool(4, pos+1) = 1;
00155 pos++;
00156 }
00157 }
00158 Matrix trans_camera_demotool = matrix_leds_camera * (matrix_leds_demotool.pseudoinverse());
00159 Rotation rot_temp; double roll, pitch, yaw;
00160 for (unsigned int i=0; i<3; i++){
00161 for (unsigned int j=0; j<3; j++)
00162 rot_temp(i,j) = trans_camera_demotool(i+1,j+1);
00163 _Frame_camera_demotool.p(i) = trans_camera_demotool(i+1,4);
00164 }
00165 rot_temp.GetRPY(roll, pitch, yaw);
00166 _Frame_camera_demotool.M = Rotation::RPY(roll, pitch, yaw);
00167 _Frame_world_demotool = _Frame_world_camera.value() * _Frame_camera_demotool;
00168
00169
00170
00171 double error = 0; Vector vec_temp;
00172 for (unsigned int i=0; i<3; i++)
00173 for (unsigned int j=0; j<3; j++)
00174 trans_camera_demotool(i+1,j+1) = _Frame_camera_demotool.M(i,j);
00175 Matrix residu = (trans_camera_demotool * matrix_leds_demotool) - matrix_leds_camera;
00176 for (unsigned int i=0; i<_num_visible_leds; i++)
00177 for (unsigned int j=0; j<3; j++)
00178 vec_temp(j) = residu(j+1, i+1);
00179 error += vec_temp.Norm() /_num_visible_leds;
00180
00181
00182
00183
00184 }
00185
00186
00187
00188
00189 _period = TimeService::Instance()->secondsSince(_time_begin);
00190 _Frame_world_manip = _Frame_world_demotool * _Frame_demotool_manip.value();
00191 if (_is_initialized)
00192 _Twist_world_manip = diff(_Frame_world_manip_old, _Frame_world_manip, _period);
00193 else
00194 _is_initialized = true;
00195 _time_begin = TimeService::Instance()->getTicks();
00196 _Frame_world_manip_old = _Frame_world_manip;
00197
00198
00199
00200
00201 _Wrench_fs_fs = _Wrench_fs_fs_port.Get();
00202
00203 _Frame_world_fs = _Frame_world_demotool * _Frame_demotool_fs.value();
00204 _Wrench_gravity_world_world.torque = (_Frame_world_demotool * _center_gravity_demotool.value())
00205 * _Wrench_gravity_world_world.force;
00206 _Wrench_world_world = (_Frame_world_fs * _Wrench_fs_fs) - _Wrench_gravity_world_world;
00207
00208
00209
00210
00211 _Frame_world_manip_port.Set(_Frame_world_manip);
00212 _Wrench_world_world_port.Set(_Wrench_world_world);
00213 _Wrench_manip_manip_port.Set(_Frame_world_manip.Inverse() * _Wrench_world_world);
00214 _Twist_world_world_port.Set(_Twist_world_manip.RefPoint(-(_Frame_world_manip.p)));
00215 _Twist_world_manip_port.Set(_Twist_world_manip);
00216 _num_visible_leds_port.Set(_num_visible_leds);
00217 }
00218
00219 void Demotool::shutdown()
00220 {
00221 marshalling()->writeProperties(_propertyfile);
00222 }
00223
00224
00225 void Demotool::calibrateWorldToManip()
00226 {
00227
00228 _Frame_world_camera.value() = _Frame_demotool_manip.value().Inverse() * _Frame_camera_demotool.Inverse();
00229 }
00230
00231 void Demotool::calibrateWrenchSensor()
00232 {
00233 log(Debug) <<this->getName()<<": calibrate with " << _Frame_world_fs.Inverse() * _Wrench_world_world
00234 <<endlog();
00235
00236 _add_offset( _Frame_world_fs.Inverse() * _Wrench_world_world );
00237 }
00238
00239
00240
00241 }
00242