constraint_app
|
00001 #include <stdio.h> 00002 #include <inttypes.h> 00003 #include <lcm/lcm.h> 00004 #include <iostream> 00005 #include <lcmtypes/visualization.h> 00006 #include <path_util/path_util.h> 00007 #include <boost/shared_ptr.hpp> 00008 #include <boost/thread.hpp> 00009 #include <boost/format.hpp> 00010 #include <lcmtypes/drc_lcmtypes.hpp> 00011 #include <lcm/lcm-cpp.hpp> 00012 #include <urdf/model.h> 00013 #include <kdl/tree.hpp> 00014 #include <kdl_parser/kdl_parser.hpp> 00015 #include <forward_kinematics/treefksolverposfull_recursive.hpp> 00016 #include <otdf_parser/otdf_parser.h> 00017 #include <otdf_parser/otdf_urdf_converter.h> 00018 #include "mytreefksolverpos_recursive.hpp" 00019 #include <bot_lcmgl_client/lcmgl.h> 00020 #include <GL/gl.h> 00021 #include <GL/glu.h> 00022 #include <lcmtypes/bot_param/update_t.hpp> 00023 #include <math.h> 00024 00025 boost::mutex idMutex; 00026 boost::condition_variable idCondition; 00027 boost::mutex readyMutex; 00028 boost::condition_variable readyCondition; 00029 volatile bool idValid = false; 00030 volatile bool matlabReady = false; 00031 volatile int affordance_id = 0; 00032 KDL::Tree tree; 00033 00034 void print_kdl_tree(const KDL::Tree& tree, 00035 const KDL::TreeElement& segment, 00036 unsigned int depth) 00037 { 00038 for ( unsigned int i = 0; i < depth; i++ ) { 00039 std::cout << " "; 00040 } 00041 std::cout << segment.segment.getName() 00042 << ", joint " << segment.segment.getJoint().getName() 00043 << " of type " << segment.segment.getJoint().getTypeName() 00044 << std::endl; 00045 for ( unsigned int i = 0; i < segment.children.size(); i++ ) { 00046 print_kdl_tree(tree, segment.children[i]->second, depth+1); 00047 } 00048 } 00049 00050 void loadTree(const std::string& filename) 00051 { 00052 // load the OTDF file 00053 std::string xml_string; 00054 if ( !otdf::get_xml_string_from_file(filename, xml_string) ) { 00055 std::cerr << "unable to get_xml_string_from_file " << filename << std::endl; 00056 exit(-1); 00057 } 00058 00059 //convert OTDF to URDF 00060 boost::shared_ptr<otdf::ModelInterface> otdf_instance(otdf::parseOTDF(xml_string)); 00061 std::string urdf_xml_string(otdf::convertObjectInstanceToCompliantURDFstring(otdf_instance)); 00062 00063 // Parse KDL tree 00064 if ( !kdl_parser::treeFromString(urdf_xml_string,tree) ) { 00065 std::cerr << "ERROR: Failed to extract kdl tree from " << otdf_instance->name_ 00066 << " otdf object instance "<< std::endl; 00067 } 00068 00069 std::cout << "created KDL object with " << tree.getNrOfJoints() << " joints and " 00070 << tree.getNrOfSegments() << " segments" << std::endl; 00071 print_kdl_tree(tree, tree.getRootSegment()->second, 0); 00072 } 00073 00074 void runPopulate(lcm::LCM* lcm) 00075 { 00076 bot_lcmgl_t* lcmgl = bot_lcmgl_init(lcm->getUnderlyingLCM(), "ca_test"); 00077 00078 std::string otdf_name("fixed_valve_task_wall3"); 00079 00080 loadTree(otdf_name); 00081 MyTreeFkSolverPos_recursive fk(tree); 00082 00083 drc::affordance_plus_t affordance_plus; 00084 drc::affordance_plus_t affordance_plus_truth; 00085 drc::affordance_t& affordance(affordance_plus.aff); 00086 affordance.utime = 0; 00087 affordance.otdf_type = otdf_name; 00088 affordance.friendly_name = "test"; 00089 affordance.uid = affordance_id; 00090 affordance.aff_store_control = drc::affordance_t::NEW; 00091 affordance.origin_xyz[0] = 0.0; 00092 affordance.origin_xyz[1] = 0.0; 00093 affordance.origin_xyz[2] = 0.0; 00094 affordance.origin_rpy[0] = 3.14; 00095 affordance.origin_rpy[1] = 0.0; 00096 affordance.origin_rpy[2] = 0.0; 00097 affordance.nparams = 0; 00098 00099 affordance.nstates = tree.getNrOfJoints(); 00100 affordance.states.resize(affordance.nstates); 00101 affordance.state_names.resize(affordance.nstates); 00102 KDL::JntArray joints(tree.getNrOfJoints()); 00103 for ( int i = 0; i < tree.getNrOfJoints(); i++ ) { 00104 affordance.states[i] = 0.0; 00105 affordance.state_names[i] = boost::str(boost::format("base_joint%i") % i); 00106 joints(i) = affordance.states[i]; 00107 } 00108 00109 affordance.bounding_xyz[0] = 0.0; 00110 affordance.bounding_xyz[1] = 0.0; 00111 affordance.bounding_xyz[2] = 0.0; 00112 affordance.bounding_rpy[0] = 0.0; 00113 affordance.bounding_rpy[1] = 0.0; 00114 affordance.bounding_rpy[2] = 0.0; 00115 affordance.bounding_lwh[0] = 0.0; 00116 affordance.bounding_lwh[1] = 0.0; 00117 affordance.bounding_lwh[2] = 0.0; 00118 affordance_plus.npoints = 0; 00119 affordance_plus.ntriangles = 0; 00120 00121 //wait for matlab to be ready 00122 { 00123 boost::mutex::scoped_lock lock(readyMutex); 00124 while ( !matlabReady ) { 00125 std::cout << "waiting on matlab to be ready" << std::endl; 00126 boost::system_time timeout = boost::get_system_time() + 00127 boost::posix_time::milliseconds(1000); 00128 readyCondition.timed_wait(lock, timeout); 00129 } 00130 } 00131 00132 // publish to the affordance server 00133 std::cout << "publishing AFFORDANCE_FIT for id=" << affordance_plus.aff.uid << std::endl; 00134 lcm->publish("AFFORDANCE_FIT", &affordance_plus); //this will draw it in the viewer for debugging 00135 00136 //wait for the next response message and retrieve the uid 00137 { 00138 boost::mutex::scoped_lock lock(idMutex); 00139 while ( !idValid ) { 00140 std::cout << "waiting on lcm message from affordance server" << std::endl; 00141 boost::system_time timeout = boost::get_system_time() + 00142 boost::posix_time::milliseconds(1000); 00143 idCondition.timed_wait(lock, timeout); 00144 } 00145 } 00146 00147 //start using this uid 00148 affordance.uid = affordance_id; 00149 std::cout << "publishing CAM_AFFORDANCE_FIT for id=" << affordance_plus.aff.uid << std::endl; 00150 lcm->publish("CAM_AFFORDANCE_FIT", &affordance_plus); //this will initialize our tracker with the fit 00151 00152 00153 int ring_segs[3] = {0, 6, 12}; 00154 KDL::Frame base_expressedIn_world; 00155 base_expressedIn_world.p[0] = affordance.origin_xyz[0]; 00156 base_expressedIn_world.p[1] = affordance.origin_xyz[1]; 00157 base_expressedIn_world.p[2] = affordance.origin_xyz[2]; 00158 base_expressedIn_world.M = KDL::Rotation::RPY(affordance.origin_rpy[0], affordance.origin_rpy[1], affordance.origin_rpy[2]); 00159 00160 affordance_plus_truth = affordance_plus; 00161 affordance_plus_truth.aff.uid++; 00162 affordance_plus_truth.aff.aff_store_control = drc::affordance_t::NEW; 00163 affordance_plus_truth.aff.origin_xyz[2] += 1.0; 00164 00165 for ( int i = 0; i < 20; i ++ ) { 00166 00167 std::cout << "publishing" << std::endl; 00168 00169 affordance.aff_store_control = drc::affordance_t::UPDATE; 00170 for ( int j = 0; j < tree.getNrOfJoints(); j++ ) { 00171 affordance.states[j] = fmod(i / 10.0 + j, 2.0 * M_PI); 00172 if ( affordance.states[j] > M_PI ) { 00173 affordance.states[j] = affordance.states[j] - 2.0 * M_PI; 00174 } 00175 joints(j) = affordance.states[j]; 00176 } 00177 00178 std::cout << "publishing ground truth " << affordance_plus_truth.aff.uid << std::endl; 00179 affordance_plus_truth.aff.states = affordance.states; 00180 lcm->publish("AFFORDANCE_FIT", &affordance_plus_truth); 00181 affordance_plus_truth.aff.aff_store_control = drc::affordance_t::UPDATE; 00182 00183 MyTreeFkSolverPos_recursive::SegmentToPoseMap map; 00184 int fkret = fk.JntToCart(joints, map); 00185 if ( fkret < 0 ) { 00186 std::cout << "error while getting forward kinematics: " << fkret << std::endl; 00187 continue; 00188 } 00189 00190 bot_lcmgl_enable(lcmgl, GL_DEPTH_TEST); 00191 bot_lcmgl_color3f(lcmgl, 1, 0, 0); 00192 bot_lcmgl_point_size(lcmgl, 3); 00193 bot_lcmgl_begin(lcmgl, LCMGL_LINES); 00194 00195 drc::affordance_track_collection_t tracks; 00196 tracks.utime = 0; 00197 tracks.uid = affordance.uid; 00198 00199 for ( MyTreeFkSolverPos_recursive::SegmentToPoseMap::const_iterator iter = map.begin(); 00200 iter != map.end(); ++iter ) { 00201 00202 for ( int j = 0; j < (otdf_name == "fixed_valve_task_wall" ? 2 : 3); j++ ) { 00203 for ( int s = 0; s < 3; s++ ) { 00204 //std::string seg( (j==0) ? boost::str(boost::format("RING_%i") % ring_segs[s] ) : 00205 // boost::str(boost::format("RING%i_%i") % (j+1) % ring_segs[s]) ); 00206 std::string spoke(boost::str(boost::format("Spokes%i_%i") % j % s)); 00207 if ( spoke == iter->first ) { 00208 00209 const KDL::Frame& pt_expressedIn_base(iter->second); 00210 double xyzrpw[6] = { pt_expressedIn_base.p[0], pt_expressedIn_base.p[1], pt_expressedIn_base.p[2], 0.0, 0.0, 0.0 }; 00211 pt_expressedIn_base.M.GetRPY(xyzrpw[3], xyzrpw[4], xyzrpw[5]); 00212 KDL::Frame pt_expressedIn_world = base_expressedIn_world * pt_expressedIn_base; 00213 KDL::Frame pt2_expressedIn_pt; 00214 pt2_expressedIn_pt.p[0] = 0.3; 00215 KDL::Frame pt3_expressedIn_pt; 00216 pt3_expressedIn_pt.p[2] = 0.3; 00217 KDL::Frame pt2_expressedIn_world = base_expressedIn_world * pt_expressedIn_base * pt2_expressedIn_pt; 00218 KDL::Frame pt3_expressedIn_world = base_expressedIn_world * pt_expressedIn_base * pt3_expressedIn_pt; 00219 std::cout << " " << iter->first << ", " << joints(j) << std::endl; 00220 00221 bot_lcmgl_vertex3f(lcmgl, pt_expressedIn_world.p[0], pt_expressedIn_world.p[1], pt_expressedIn_world.p[2]); 00222 bot_lcmgl_vertex3f(lcmgl, pt2_expressedIn_world.p[0], pt2_expressedIn_world.p[1], pt2_expressedIn_world.p[2]); 00223 00224 bot_lcmgl_vertex3f(lcmgl, pt_expressedIn_world.p[0], pt_expressedIn_world.p[1], pt_expressedIn_world.p[2]); 00225 bot_lcmgl_vertex3f(lcmgl, pt3_expressedIn_world.p[0], pt3_expressedIn_world.p[1], pt3_expressedIn_world.p[2]); 00226 00227 drc::affordance_track_t track; 00228 track.segment = iter->first; 00229 track.position.x = pt_expressedIn_world.p[0]; 00230 track.position.y = pt_expressedIn_world.p[1]; 00231 track.position.z = pt_expressedIn_world.p[2]; 00232 track.id = 0; 00233 00234 tracks.tracks.push_back(track); 00235 } 00236 } 00237 } 00238 } 00239 00240 tracks.ntracks = tracks.tracks.size(); 00241 lcm->publish("AFFORDANCE_DETECTIONS", &tracks); 00242 00243 bot_lcmgl_end(lcmgl); 00244 bot_lcmgl_switch_buffer(lcmgl); 00245 00246 boost::this_thread::sleep(boost::posix_time::seconds(2)); 00247 } 00248 00249 std::cout << "done publishing" << std::endl; 00250 bot_lcmgl_destroy(lcmgl); 00251 00252 exit(0); 00253 } 00254 00255 class dummy { 00256 public: 00257 void handleAffordanceCollection(const lcm::ReceiveBuffer* rbuf, 00258 const std::string& channel, 00259 const drc::affordance_plus_collection_t *affordance_plus_col) 00260 { 00261 boost::mutex::scoped_lock lock(idMutex); 00262 00263 std::cout << "got a collection" << std::endl; 00264 00265 if ( idValid ) { 00266 std::cout << "ignoring collection" << std::endl; 00267 return; 00268 } 00269 00270 if ( affordance_plus_col->naffs == 0 ) return; 00271 00272 for ( int i = 0; i < affordance_plus_col->naffs; i++ ) { 00273 if ( affordance_plus_col->affs_plus[i].aff.friendly_name == "test" ) { 00274 int this_uid = affordance_plus_col->affs_plus[i].aff.uid; 00275 if ( this_uid >= affordance_id ) { 00276 affordance_id = this_uid; 00277 std::cout << " " << affordance_id << std::endl; 00278 } 00279 } 00280 } 00281 00282 idValid = true; 00283 idCondition.notify_all(); 00284 } 00285 00286 void handleTrackPFStatus(const lcm::ReceiveBuffer* rbuf, 00287 const std::string& channel, 00288 const bot_param::update_t *update) 00289 { 00290 if ( update->params == "READY" ) { 00291 boost::mutex::scoped_lock lock(readyMutex); 00292 matlabReady = true; 00293 readyCondition.notify_all(); 00294 } 00295 } 00296 }; 00297 00298 int main(int argc, char ** argv) 00299 { 00300 lcm::LCM lcm; 00301 dummy d; 00302 00303 lcm.subscribe("AFFORDANCE_PLUS_COLLECTION", &dummy::handleAffordanceCollection, &d); 00304 lcm.subscribe("TRACK_PF_STATUS", &dummy::handleTrackPFStatus, &d); 00305 00306 std::cout << "starting..." << std::endl; 00307 boost::thread populateThread = boost::thread(runPopulate, &lcm); 00308 00309 while (0 == lcm.handle()) { 00310 00311 00312 } 00313 00314 return 0; 00315 }