Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <string>
00019
00020 #include <gazebo/math/Pose.hh>
00021 #include <gazebo/math/Vector3.hh>
00022 #include <gazebo/math/Quaternion.hh>
00023
00024 #include "osrf_gear/AriacScorer.h"
00025
00027 AriacScorer::AriacScorer()
00028 {
00029 }
00030
00032 AriacScorer::~AriacScorer()
00033 {
00034 }
00035
00037 ariac::GameScore AriacScorer::GetGameScore()
00038 {
00039 return this->gameScore;
00040 }
00041
00043 ariac::GoalScore AriacScorer::GetCurrentGoalScore()
00044 {
00045 return *this->goalScore;
00046 }
00047
00049 void AriacScorer::Update(double timeStep)
00050 {
00051 if (this->isPartTravelling)
00052 {
00053 this->gameScore.partTravelTime += timeStep;
00054 }
00055
00056 boost::mutex::scoped_lock kitTraysLock(this->kitTraysMutex);
00057
00058 if (this->newGoalReceived)
00059 {
00060 this->AssignGoal(this->newGoal);
00061 }
00062
00063
00064 auto v = std::getenv("ARIAC_COMPETITION");
00065 if (!v)
00066 {
00067
00068 if (this->newGoalReceived || this->newTrayInfoReceived)
00069 {
00070 this->ScoreCurrentState();
00071 }
00072 }
00073
00074 this->newGoalReceived = false;
00075 this->newTrayInfoReceived = false;
00076 }
00077
00079 bool AriacScorer::IsCurrentGoalComplete()
00080 {
00081 return this->goalScore->isComplete();
00082 }
00083
00085 void AriacScorer::ScoreCurrentState()
00086 {
00087 for (const auto & item : this->kitTrays)
00088 {
00089 auto trayID = item.first;
00090 auto tray = item.second;
00091 if (tray.currentKit.kitType != "")
00092 {
00093 auto trayScore = ScoreTray(tray);
00094 ROS_INFO_STREAM("Score from tray '" << trayID <<
00095 "' with kit type '" << tray.currentKit.kitType << "': " << trayScore.total());
00096 }
00097 else
00098 {
00099 for (const auto & item : this->currentGoal.kits)
00100 {
00101 auto kit = item.second;
00102 auto goalKitType = kit.kitType;
00103 tray.currentKit.kitType = goalKitType;
00104 auto trayScore = ScoreTray(tray);
00105 ROS_INFO_STREAM("Score from tray '" << trayID
00106 << "' if it were to have kit type '" << goalKitType << "': "
00107 << trayScore.total());
00108 }
00109 }
00110 }
00111 }
00112
00114 bool AriacScorer::GetTrayById(const ariac::TrayID_t & trayID, ariac::KitTray & kitTray)
00115 {
00116 auto it = this->kitTrays.find(trayID);
00117 if (it == this->kitTrays.end())
00118 {
00119 ROS_DEBUG_STREAM("No known tray with ID: " << trayID);
00120 return false;
00121 }
00122 kitTray = it->second;
00123 return true;
00124 }
00125
00127 ariac::TrayScore AriacScorer::SubmitTray(const ariac::KitTray & tray)
00128 {
00129 auto trayScore = ScoreTray(tray);
00130 ROS_DEBUG_STREAM("Score from tray '" << tray.trayID << "': " << trayScore.total());
00131 this->goalScore->trayScores[tray.trayID] = trayScore;
00132 return trayScore;
00133 }
00134
00136 ariac::TrayScore AriacScorer::ScoreTray(const ariac::KitTray & tray)
00137 {
00138 ariac::Kit kit = tray.currentKit;
00139 ariac::KitType_t kitType = tray.currentKit.kitType;
00140 ariac::TrayScore score;
00141 if (this->currentGoal.kits.find(kitType) == this->currentGoal.kits.end())
00142 {
00143 ROS_DEBUG_STREAM("No known kit type: " << kitType);
00144 return score;
00145 }
00146 ariac::Kit assignedKit = this->currentGoal.kits[kitType];
00147 auto numAssignedObjects = assignedKit.objects.size();
00148 ROS_DEBUG_STREAM("Comparing the " << numAssignedObjects <<
00149 " assigned objects with the current " <<
00150 kit.objects.size() << " objects");
00151
00152
00153 std::map<std::string, unsigned int> assignedObjectTypeCount, currentObjectTypeCount;
00154 for (const auto & obj : assignedKit.objects)
00155 {
00156 if (assignedObjectTypeCount.find(obj.type) == assignedObjectTypeCount.end())
00157 {
00158 assignedObjectTypeCount[obj.type] = 0;
00159 }
00160 assignedObjectTypeCount[obj.type] += 1;
00161 }
00162
00163 ROS_DEBUG_STREAM("Checking object counts");
00164
00165 bool assignedObjectsMissing = false;
00166 for (auto & value : assignedObjectTypeCount)
00167 {
00168 auto assignedObjectType = value.first;
00169 auto assignedObjectCount = value.second;
00170 auto currentObjectCount =
00171 std::count_if(kit.objects.begin(), kit.objects.end(),
00172 [assignedObjectType](ariac::KitObject k) {return k.type == assignedObjectType;});
00173 ROS_DEBUG_STREAM("Found " << currentObjectCount <<
00174 " objects of type '" << assignedObjectType << "'");
00175 score.partPresence +=
00176 std::min(long(assignedObjectCount), currentObjectCount) * scoringParameters.objectPresence;
00177 if (currentObjectCount < assignedObjectCount)
00178 {
00179 assignedObjectsMissing = true;
00180 }
00181 }
00182 if (!assignedObjectsMissing)
00183 {
00184 ROS_DEBUG_STREAM("All objects on tray");
00185 score.allPartsBonus += scoringParameters.allObjectsBonusFactor * numAssignedObjects;
00186 }
00187
00188 ROS_DEBUG_STREAM("Checking object poses");
00189
00190
00191 std::vector<ariac::KitObject> remainingAssignedObjects(assignedKit.objects);
00192
00193 for (const auto & currentObject : kit.objects)
00194 {
00195 for (auto it = remainingAssignedObjects.begin(); it != remainingAssignedObjects.end(); ++it)
00196 {
00197
00198 auto assignedObject = *it;
00199 if (assignedObject.type != currentObject.type)
00200 continue;
00201
00202
00203 ROS_DEBUG_STREAM("Comparing pose '" << currentObject.pose <<
00204 "' with the assigned pose '" << assignedObject.pose << "'");
00205 gazebo::math::Vector3 posnDiff = assignedObject.pose.CoordPositionSub(currentObject.pose);
00206 posnDiff.z = 0;
00207 if (posnDiff.GetLength() > scoringParameters.distanceThresh)
00208 continue;
00209 ROS_DEBUG_STREAM("Object of type '" << currentObject.type <<
00210 "' in the correct position");
00211 score.partPose += scoringParameters.objectPosition;
00212
00213
00214 gazebo::math::Quaternion objOrientation = currentObject.pose.rot;
00215 gazebo::math::Quaternion goalOrientation = assignedObject.pose.rot;
00216
00217
00218
00219 double orientationDiff = objOrientation.Dot(goalOrientation);
00220
00221
00222 double quaternionDiffThresh = 0.05;
00223 if (std::abs(orientationDiff) < (1.0 - quaternionDiffThresh))
00224 continue;
00225
00226
00227 double yawDiff = objOrientation.GetYaw() - goalOrientation.GetYaw();
00228 if (std::abs(yawDiff) > scoringParameters.orientationThresh)
00229 continue;
00230
00231 ROS_DEBUG_STREAM("Object of type '" << currentObject.type <<
00232 "' in the correct orientation");
00233 score.partPose += scoringParameters.objectOrientation;
00234
00235
00236 remainingAssignedObjects.erase(it);
00237 break;
00238 }
00239 }
00240
00241
00242 if (remainingAssignedObjects.empty())
00243 {
00244 score.isComplete = true;
00245 }
00246
00247 return score;
00248 }
00249
00251 void AriacScorer::OnTrayInfoReceived(const osrf_gear::KitTray::ConstPtr & trayMsg)
00252 {
00253 boost::mutex::scoped_lock kitTraysLock(this->kitTraysMutex);
00254
00255
00256 std::string trayID = trayMsg->tray.data;
00257
00258 if (this->kitTrays.find(trayID) == this->kitTrays.end())
00259 {
00260
00261 this->kitTrays[trayID] = ariac::KitTray(trayID);
00262 }
00263
00264
00265
00266
00267
00268 this->newTrayInfoReceived = true;
00269 ariac::Kit kitState;
00270 FillKitFromMsg(trayMsg->kit, kitState);
00271 this->kitTrays[trayID].UpdateKitState(kitState);
00272 }
00273
00275 void AriacScorer::OnGoalReceived(const osrf_gear::Goal::ConstPtr & goalMsg)
00276 {
00277 ROS_DEBUG("Received a goal");
00278 this->newGoalReceived = true;
00279
00280 ariac::Goal goal;
00281 goal.goalID = goalMsg->goal_id.data;
00282 for (const auto & kitMsg : goalMsg->kits)
00283 {
00284 ariac::KitType_t kitType = kitMsg.kit_type.data;
00285 ariac::Kit assignedKit;
00286 FillKitFromMsg(kitMsg, assignedKit);
00287 goal.kits[kitType] = assignedKit;
00288 }
00289 this->newGoal = goal;
00290 }
00291
00293 void AriacScorer::AssignGoal(const ariac::Goal & goal)
00294 {
00295 ariac::GoalID_t goalID = goal.goalID;
00296 if (this->gameScore.goalScores.find(goalID) == this->gameScore.goalScores.end())
00297 {
00298
00299 this->gameScore.goalScores[goalID] = ariac::GoalScore();
00300 this->gameScore.goalScores[goalID].goalID = goalID;
00301 }
00302 this->goalScore = &this->gameScore.goalScores[goalID];
00303
00304 this->currentGoal = goal;
00305 }
00306
00308 ariac::GoalScore AriacScorer::UnassignCurrentGoal(double timeTaken)
00309 {
00310 auto goalScore = *this->goalScore;
00311 goalScore.timeTaken = timeTaken;
00312 this->currentGoal.kits.clear();
00313 return goalScore;
00314 }
00315
00317 void AriacScorer::FillKitFromMsg(const osrf_gear::Kit &kitMsg, ariac::Kit &kit)
00318 {
00319 kit.objects.clear();
00320 for (const auto & objMsg : kitMsg.objects)
00321 {
00322 ariac::KitObject obj;
00323 obj.type = ariac::DetermineModelType(objMsg.type);
00324 geometry_msgs::Point p = objMsg.pose.position;
00325 geometry_msgs::Quaternion o = objMsg.pose.orientation;
00326 gazebo::math::Vector3 objPosition(p.x, p.y, p.z);
00327 gazebo::math::Quaternion objOrientation(o.w, o.x, o.y, o.z);
00328 obj.pose = gazebo::math::Pose(objPosition, objOrientation);
00329 kit.objects.push_back(obj);
00330 }
00331 }
00332
00334 void AriacScorer::OnGripperStateReceived(const osrf_gear::VacuumGripperState &stateMsg)
00335 {
00336 this->isPartTravelling = stateMsg.enabled && stateMsg.attached;
00337 }