constraint_app
/home/jbrooksh/drc/software/perception/constraint_app/src/matlab_mex/ConstraintApp_RB_UKF.cpp
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs