constraint_app
|
00001 #include "ConstraintApp_RB_UKF.h" 00002 00003 //input: "AFFORDANCE_TRACK_COLLECTION" has incoming 3d points from sudeep 00004 // includes a "segment" string which is the "id" and a 3d point to track for each "affordance" 00005 00006 //input: "AFFORDANCE_FIT" a new affordance_t() type. this includes (x,y,z,r,p,w) as params. 00007 // might contain other joints too, but we don't track them yet. when this arrives, it's a reset to our system. 00008 00009 //output: "AFFORDANCE_JOINT_ANGLES" affordance_t() type. our best estimate of the (x,y,z,r,p,w) 00010 00011 // when a new AFFORDANCE_FIT arrives, remove all existing relative poses. 00012 // when a AFFORDANCE_TRACK_COLLECTION arrives... 00013 // if a track has been seen before, then this is a new observation 00014 // if a track has not been seen before, then the position of this (x,y,z) relative to the current base pose is the new pose used for expected observations 00015 00016 // when a AFFORDANCE_TRACK_COLLECTION 00017 // add noise to the current best estimate of pose 00018 // perform the update step. use the relative poses as expected observations, use new data as new observations. 00019 00020 00021 ConstraintApp_RB_UKF::ConstraintApp_RB_UKF() : ConstraintApp(), m_wasReset(true), m_nextLinkId(0) 00022 { 00023 } 00024 00025 ConstraintApp_RB_UKF::~ConstraintApp_RB_UKF() 00026 { 00027 m_log << "ConstraintApp_RB_UKF::~ConstraintApp_RB_UKF" << std::endl; 00028 } 00029 00030 void ConstraintApp_RB_UKF::AffordanceTrackCollectionHandler(const drc::affordance_track_collection_t *msg) 00031 { 00032 m_log << "got a new track collection" << std::endl; 00033 00034 boost::mutex::scoped_lock lock(m_dataMutex); 00035 00036 for ( int i = 0; i < msg->ntracks; i++ ) { 00037 const drc::affordance_track_t* track = &msg->tracks[i]; 00038 00039 int trackId(track->id); 00040 KDL::Vector track_expressedIn_world(track->position.x, track->position.y, track->position.z); 00041 KDL::Vector track_expressedIn_base(m_currentEstimate.base_expressedIn_world.Inverse() * track_expressedIn_world); 00042 00043 if ( m_currentLinks.find(trackId) == m_currentLinks.end() ) { 00044 //this track is a new one 00045 m_currentLinks.insert(std::pair<int, Link>(trackId, Link(track_expressedIn_base, m_nextLinkId++))); 00046 m_log << " creating a new link for id \"" << trackId << "\"" << std::endl 00047 << " world pose: " << track_expressedIn_world << std::endl 00048 << " base pose: " << track_expressedIn_base << std::endl; 00049 } else { 00050 //this track is already known, just add this report as an observation 00051 ObservationMap::iterator existingObs(m_currentObservations.find(trackId)); 00052 Observation newobs(track_expressedIn_world); 00053 if ( existingObs == m_currentObservations.end() ) { 00054 //we have not yet observed this link, so add it 00055 m_currentObservations.insert(std::pair<int, Observation>(trackId, newobs)); 00056 m_log << " new observation for segment \"" << trackId << "\"" << std::endl 00057 << " world pose: " << track_expressedIn_world << std::endl; 00058 } else { 00059 //we've observed, and have not yet processed. just update the observation 00060 existingObs->second = newobs; 00061 m_log << " repeat observation for id \"" << trackId << "\"" << std::endl 00062 << " world pose: " << track_expressedIn_world << std::endl; 00063 } 00064 } 00065 } 00066 00067 m_dataCondition.notify_all(); 00068 00069 /* 00070 m_log << "sent a new (empty) estimate of joint angles" << std::endl; 00071 drc_affordance_joint_angles_t aja; 00072 aja.utime = msg->utime; 00073 aja.uid = msg->uid; 00074 drc_affordance_joint_angles_t_publish(m_lcm, "AFFORDANCE_JOINT_ANGLES", &aja); 00075 */ 00076 } 00077 00078 void ConstraintApp_RB_UKF::AffordanceFitHandler(const drc::affordance_t *msg) 00079 { 00080 m_log << "got a new affordance fit" << std::endl; 00081 00082 boost::mutex::scoped_lock lock(m_dataMutex); 00083 boost::optional<KDL::Frame> msgFrame(GetFrameFromParams(msg)); 00084 if ( !msgFrame ) { 00085 m_log << "ERROR: unable to extract base pose from msg" << std::endl; 00086 return; 00087 } 00088 m_currentEstimate.base_expressedIn_world = *msgFrame; 00089 m_currentLinks.clear(); 00090 m_currentObservations.clear(); 00091 m_wasReset = true; 00092 00093 m_log << " reset the base pose to " << std::endl 00094 << m_currentEstimate.base_expressedIn_world << std::endl; 00095 } 00096 00097 bool ConstraintApp_RB_UKF::WaitForObservations(unsigned int timeout_ms) 00098 { 00099 m_log << "ConstraintApp_RB_UKF::WaitForObservations, timeout = " << timeout_ms << std::endl; 00100 00101 boost::mutex::scoped_lock lock(m_dataMutex); 00102 00103 if ( !m_currentObservations.empty() ) return true; 00104 00105 boost::system_time timeout = boost::get_system_time() + boost::posix_time::milliseconds(timeout_ms); 00106 m_dataCondition.timed_wait(lock, timeout); 00107 00108 return !m_currentObservations.empty(); 00109 } 00110 00111 bool ConstraintApp_RB_UKF::GetExpectedObservations(const std::vector<double>& state, 00112 const std::vector<int>& observationIds, 00113 std::vector<double>& observations) 00114 { 00115 boost::mutex::scoped_lock lock(m_dataMutex); 00116 00117 m_log << "ConstraintApp_RB_UKF::GetExpectedObservations" << std::endl; 00118 00119 observations.clear(); 00120 observations.reserve(observationIds.size()*3); 00121 00122 for ( std::vector<int>::const_iterator iter = observationIds.begin(); iter != observationIds.end(); ++iter ) { 00123 00124 //find the id; TODO: need to make this a search tree 00125 LinkMap::const_iterator linkIter; 00126 for ( linkIter = m_currentLinks.begin(); linkIter != m_currentLinks.end(); ++linkIter ) { 00127 if ( linkIter->second.id == *iter ) break; 00128 } 00129 00130 if ( linkIter == m_currentLinks.end() ) { 00131 m_log << "ERROR: unable to find corresponding link " << *iter; 00132 return false; 00133 } 00134 00135 KDL::Frame base_expressedIn_world(VectorToFrame(state)); 00136 KDL::Vector expected = base_expressedIn_world * linkIter->second.link_expressedIn_base; 00137 observations.push_back(expected[0]); 00138 observations.push_back(expected[1]); 00139 observations.push_back(expected[2]); 00140 00141 m_log << " added expected observation for " << linkIter->first << ", id=" << *iter << std::endl 00142 << " exp: " << expected << std::endl; 00143 } 00144 return true; 00145 } 00146 00147 bool ConstraintApp_RB_UKF::GetObservations(std::vector<double>& actualObservations, 00148 std::vector<int>& observationIds) 00149 { 00150 boost::mutex::scoped_lock lock(m_dataMutex); 00151 00152 m_log << "ConstraintApp_RB_UKF::GetObservations" << std::endl; 00153 00154 actualObservations.clear(); 00155 observationIds.clear(); 00156 00157 actualObservations.reserve(m_currentObservations.size()*3); 00158 observationIds.reserve(m_currentObservations.size()); 00159 00160 for ( ObservationMap::const_iterator iter = m_currentObservations.begin(); iter != m_currentObservations.end(); ++iter ) { 00161 actualObservations.push_back(iter->second.obs_expressedIn_world[0]); 00162 actualObservations.push_back(iter->second.obs_expressedIn_world[1]); 00163 actualObservations.push_back(iter->second.obs_expressedIn_world[2]); 00164 00165 LinkMap::const_iterator linkIter = m_currentLinks.find(iter->first); 00166 if ( linkIter == m_currentLinks.end() ) { 00167 m_log << "ERROR: unable to find a corresponding link for observation " << iter->first << std::endl; 00168 return false; 00169 } 00170 00171 observationIds.push_back(linkIter->second.id); 00172 00173 m_log << " added observation for id " << iter->first << std::endl 00174 << " obs: " << iter->second.obs_expressedIn_world << std::endl 00175 << " my id: " << linkIter->second.id << std::endl; 00176 } 00177 00178 m_currentObservations.clear(); 00179 00180 return true; 00181 } 00182 00183 bool ConstraintApp_RB_UKF::GetResetAndClear() 00184 { 00185 boost::mutex::scoped_lock lock(m_dataMutex); 00186 bool ret = m_wasReset; 00187 m_wasReset = false; 00188 return ret; 00189 } 00190 00191 void ConstraintApp_RB_UKF::GetCurrentStateEstimate(std::vector<double>& state) 00192 { 00193 boost::mutex::scoped_lock lock(m_dataMutex); 00194 state = FrameToVector(m_currentEstimate.base_expressedIn_world); 00195 } 00196 00197 void ConstraintApp_RB_UKF::SetCurrentStateEstimate(const std::vector<double>& state) 00198 { 00199 boost::mutex::scoped_lock lock(m_dataMutex); 00200 m_currentEstimate.base_expressedIn_world = VectorToFrame(state); 00201 }