constraint_app
|
00001 #include "ConstraintApp_MB.h" 00002 #include <boost/format.hpp> 00003 #include "mytreefksolverpos_recursive.hpp" 00004 00005 ConstraintApp_MB::ConstraintApp_MB() : ConstraintApp(), m_wasReset(true) 00006 { 00007 m_log << "ConstraintApp_MB::ConstraintApp_MB: built at " << __DATE__ << " " << __TIME__ << std::endl; 00008 } 00009 00010 ConstraintApp_MB::~ConstraintApp_MB() 00011 { 00012 m_log << "ConstraintApp_MB::~ConstraintApp_MB" << std::endl; 00013 } 00014 00015 void ConstraintApp_MB::AffordanceTrackCollectionHandler(const drc::affordance_track_collection_t *msg) 00016 { 00017 boost::mutex::scoped_lock lock(m_dataMutex); 00018 00019 /* 00020 if ( msg->uid != m_affordanceUID ) { 00021 m_log << "WARNING: received track collection for uid=" << msg->uid 00022 << ", but expecting for uid=" << m_affordanceUID 00023 << ". ignoring tracks." << std::endl; 00024 return; 00025 } 00026 */ 00027 00028 m_log << "got a new track collection for affordance with uid=" << msg->uid << std::endl; 00029 00030 KDL::Tree& tree(m_affordance->GetTree()); 00031 const KDL::SegmentMap& segmentMap(tree.getSegments()); 00032 00033 for ( int i = 0; i < msg->ntracks; i++ ) { 00034 const drc::affordance_track_t* track = &msg->tracks[i]; 00035 m_log << " track: segment=" << track->segment << ", id=" << track->id << std::endl; 00036 00037 KDL::Vector track_expressedIn_world(track->position.x, track->position.y, 00038 track->position.z); 00039 00040 std::string segmentName(track->segment); 00041 KDL::SegmentMap::const_iterator segmentIter(segmentMap.find(segmentName)); 00042 if ( segmentIter == segmentMap.end() ) { 00043 m_log << "ERROR: " << segmentName << " was not found in tree" << std::endl; 00044 continue; 00045 } 00046 const KDL::Segment& parentSegment(segmentIter->second.segment); 00047 00048 //this is an existing observation 00049 ObservationMap::iterator existingObs(m_currentObservations.find(segmentName)); 00050 Observation newobs(track_expressedIn_world); 00051 if ( existingObs == m_currentObservations.end() ) { 00052 //we have not yet observed this link, so add it 00053 m_currentObservations.insert(std::pair<std::string, Observation>(segmentName, newobs)); 00054 m_log << " new observation for " << segmentName << std::endl 00055 << " world pose: " << track_expressedIn_world << std::endl; 00056 } else { 00057 //we've observed, and have not yet processed. just update the observation 00058 existingObs->second = newobs; 00059 m_log << " repeat observation for " << segmentName << std::endl 00060 << " world pose: " << track_expressedIn_world << std::endl; 00061 } 00062 } 00063 00064 m_dataCondition.notify_all(); 00065 } 00066 00067 void ConstraintApp_MB::AffordanceFitHandler(const drc::affordance_plus_t *msg) 00068 { 00069 boost::mutex::scoped_lock lock(m_dataMutex); 00070 00071 Affordance::Ptr msgAffordance(new Affordance(msg->aff.otdf_type, m_log)); 00072 Affordance::StateVector msgState; 00073 if ( msgAffordance->GetStateFromMsg(msg->aff, msgState) ) { 00074 m_affordance = msgAffordance; 00075 m_fastFKSolver = boost::shared_ptr<FastFKSolver>(new FastFKSolver(m_affordance->m_tree)); 00076 m_affordanceUID = msg->aff.uid; 00077 m_wasReset = true; 00078 m_currentState = msgState; 00079 m_prevFit = *msg; //this is a deep copy in c++ version of lcm 00080 m_log << "ConstraintApp_MB::AffordanceFitHandler: updated new affordance and state" << std::endl; 00081 m_affordance->PrintState(msgState); 00082 } else { 00083 m_log << "ConstraintApp_MB::AffordanceFitHandler: unable to create new afforance due to invalid state" << std::endl; 00084 } 00085 } 00086 00087 bool ConstraintApp_MB::GetResetAndClear() 00088 { 00089 boost::mutex::scoped_lock lock(m_dataMutex); 00090 bool ret = m_wasReset; 00091 m_wasReset = false; 00092 return ret; 00093 } 00094 00095 void ConstraintApp_MB::GetCurrentStateEstimate(StateVector& state) 00096 { 00097 boost::mutex::scoped_lock lock(m_dataMutex); 00098 state = m_currentState; 00099 } 00100 00101 void ConstraintApp_MB::SetCurrentStateEstimate(const StateVector& state) 00102 { 00103 boost::mutex::scoped_lock lock(m_dataMutex); 00104 m_currentState = state; 00105 00106 PublishFitMessage(); 00107 } 00108 00109 bool ConstraintApp_MB::WaitForObservations(unsigned int timeout_ms) 00110 { 00111 m_log << "ConstraintApp_MB::WaitForObservations, timeout = " << timeout_ms << std::endl; 00112 00113 boost::mutex::scoped_lock lock(m_dataMutex); 00114 00115 if ( !m_currentObservations.empty() ) return true; 00116 00117 boost::system_time timeout = boost::get_system_time() + boost::posix_time::milliseconds(timeout_ms); 00118 m_dataCondition.timed_wait(lock, timeout); 00119 00120 return !m_currentObservations.empty(); 00121 } 00122 00123 bool ConstraintApp_MB::GetObservations(ObservationVector& actualObservations, 00124 IdVector& observationIds) 00125 { 00126 boost::mutex::scoped_lock lock(m_dataMutex); 00127 00128 //m_log << "ConstraintApp_MB::GetObservations" << std::endl; 00129 00130 actualObservations.clear(); 00131 observationIds.clear(); 00132 00133 actualObservations.reserve(m_currentObservations.size()*3); 00134 observationIds.reserve(m_currentObservations.size()); 00135 00136 for ( ObservationMap::const_iterator iter = m_currentObservations.begin(); 00137 iter != m_currentObservations.end(); ++iter ) { 00138 actualObservations.push_back(iter->second.obs_expressedIn_world[0]); 00139 actualObservations.push_back(iter->second.obs_expressedIn_world[1]); 00140 actualObservations.push_back(iter->second.obs_expressedIn_world[2]); 00141 00142 observationIds.push_back(iter->first); 00143 00144 //m_log << " added observation for id " << iter->first << std::endl 00145 // << " obs: " << iter->second.obs_expressedIn_world << std::endl; 00146 } 00147 00148 m_currentObservations.clear(); 00149 00150 return true; 00151 } 00152 00153 /* 00154 bool ConstraintApp_MB::GetExpectedObservations(const StateVector& state, 00155 const IdVector& observationIds, 00156 ObservationVector& observations) 00157 { 00158 boost::mutex::scoped_lock lock(m_dataMutex); 00159 00160 m_log << "ConstraintApp_MB::GetExpectedObservations" << std::endl; 00161 00162 observations.clear(); 00163 observations.reserve(observationIds.size()*3); 00164 00165 KDL::JntArray joints(state.size()); 00166 m_affordance->DecodeState(state, joints); 00167 00168 MyTreeFkSolverPos_recursive fk(m_affordance->m_tree); 00169 MyTreeFkSolverPos_recursive::SegmentToPoseMap map; 00170 int fkret = fk.JntToCart(joints, map); 00171 if ( fkret < 0 ) { 00172 std::cout << "ConstraintApp_HCA::GetExpectedObservations: error while getting forward kinematics." << std::endl; 00173 return false; 00174 } 00175 00176 for ( int i = 0; i < observationIds.size(); i++ ) { 00177 MyTreeFkSolverPos_recursive::SegmentToPoseMap::const_iterator iter = map.find(observationIds[i]); 00178 if ( iter == map.end() ) { 00179 std::cout << "ConstraintApp_HCA::GetExpectedObservations: unable to find pose for segment " 00180 << observationIds[i] << std::endl; 00181 return false; 00182 } 00183 const KDL::Frame& frame(iter->second); 00184 00185 observations.push_back(frame.p[0]); 00186 observations.push_back(frame.p[1]); 00187 observations.push_back(frame.p[2]); 00188 } 00189 00190 return true; 00191 } 00192 */ 00193 00194 bool ConstraintApp_MB::GetExpectedObservations(const StateVector& state, 00195 const IdVector& observationIds, 00196 ObservationVector& observations) 00197 { 00198 boost::mutex::scoped_lock lock(m_dataMutex); 00199 00200 //m_log << "ConstraintApp_MB::GetExpectedObservations" << std::endl; 00201 00202 observations.clear(); 00203 observations.reserve(observationIds.size()*3); 00204 00205 KDL::JntArray joints(state.size()); 00206 m_affordance->DecodeState(state, joints); 00207 m_fastFKSolver->setJointPositions(joints); 00208 00209 //KDL::Tree& tree(m_affordance->GetTree()); 00210 //const KDL::SegmentMap& segmentMap(tree.getSegments()); 00211 00212 for ( IdVector::const_iterator iter = observationIds.begin(); 00213 iter != observationIds.end(); ++iter ) { 00214 00215 std::string trackSegmentName(*iter); 00216 /* 00217 KDL::SegmentMap::const_iterator obsIter(segmentMap.find(trackSegmentName)); 00218 if ( obsIter == segmentMap.end() ) { 00219 m_log << "ERROR: unable to find corresponding segment: " << *iter << std::endl; 00220 return false; 00221 } 00222 00223 KDL::Frame track_expressedIn_world; 00224 if ( !m_affordance->GetSegmentExpressedInWorld(trackSegmentName, state, 00225 track_expressedIn_world) ) { 00226 m_log << "ERROR: unable to decode current state. not processing any further expected observations." << std::endl; 00227 return false; 00228 } 00229 */ 00230 KDL::Frame track_expressedIn_world; 00231 if ( !m_fastFKSolver->getFrame(*iter, track_expressedIn_world) ) { 00232 m_log << "ERROR: unable to decode current state. not processing any further expected observations." << std::endl; 00233 return false; 00234 } 00235 00236 /* 00237 m_log << "old_output: " << track_expressedIn_world << std::endl 00238 << "new_output: " << track_expressedIn_world2 << std::endl; 00239 */ 00240 00241 observations.push_back(track_expressedIn_world.p[0]); 00242 observations.push_back(track_expressedIn_world.p[1]); 00243 observations.push_back(track_expressedIn_world.p[2]); 00244 00245 /* 00246 m_log << " added expected observation for " << trackSegmentName << std::endl 00247 << " exp: " << track_expressedIn_world.p << std::endl; 00248 */ 00249 } 00250 return true; 00251 } 00252 00253 int ConstraintApp_MB::GetStateSize() 00254 { 00255 return m_currentState.size(); 00256 } 00257 00258 void ConstraintApp_MB::PublishFitMessage() 00259 { 00260 drc::affordance_plus_t newMsg = m_prevFit; 00261 drc::affordance_t& affordance(newMsg.aff); 00262 00263 affordance.aff_store_control = drc::affordance_t::UPDATE; 00264 affordance.origin_xyz[0] = m_currentState[0]; 00265 affordance.origin_xyz[1] = m_currentState[1]; 00266 affordance.origin_xyz[2] = m_currentState[2]; 00267 affordance.origin_rpy[0] = m_currentState[3]; 00268 affordance.origin_rpy[1] = m_currentState[4]; 00269 affordance.origin_rpy[2] = m_currentState[5]; 00270 00271 std::vector<std::string> jointNames; 00272 m_affordance->GetJointNames(jointNames); 00273 00274 assert(affordance.nstates == jointNames.size()-6); 00275 00276 for(int i = 6; i < jointNames.size(); i++ ) { 00277 affordance.states[i-6] = m_currentState[i]; 00278 affordance.state_names[i-6] = jointNames[i]; 00279 } 00280 00281 m_lcm->publish("AFFORDANCE_FIT", &newMsg); 00282 } 00283 00284 bool ConstraintApp_MB::GetJacobian(const StateVector& state, 00285 const IdVector& observationIds, 00286 ConstraintApp_MB::Jacobian& jacobian, 00287 int method /*= 1*/) 00288 { 00289 const StateVector& eulerState(state); 00290 00291 // the KDL jacobian is (observation twists) x (delta euler state & delta joint angles) 00292 // our Jacobiain is (observation positions) x (delta euler state & delta joint angles) 00293 jacobian.resize(observationIds.size()*3, eulerState.size()); 00294 00295 for ( int i = 0; i < observationIds.size(); i++ ) { 00296 KDL::Jacobian thisObservationJacobian; 00297 if ( method == 1 ) { 00298 if ( !m_affordance->GetSegmentJacobianExpressedInWorld(observationIds[i], 00299 eulerState, 00300 thisObservationJacobian) ) { 00301 std::cout << "ERROR: GetJacobian: unable to find " 00302 << observationIds[i] << " segment" << std::endl; 00303 return false; 00304 } 00305 } else if ( method == 2 ) { 00306 if ( !m_affordance->GetSegmentJacobianExpressedInWorld2(observationIds[i], 00307 eulerState, 00308 thisObservationJacobian) ) { 00309 std::cout << "ERROR: GetJacobian: unable to find " 00310 << observationIds[i] << " segment" << std::endl; 00311 return false; 00312 } 00313 } else { 00314 std::cout << "ERROR: GetJacobian: invalid method=" << method << std::endl; 00315 return false; 00316 } 00317 00318 //the first 3 rows contain the position jacobian 00319 jacobian.middleRows<3>(i*3) = thisObservationJacobian.data.topRows(3); 00320 } 00321 00322 return true; 00323 }