Go to the documentation of this file.00001 #include <vigir_step_control/step_queue.h>
00002
00003
00004
00005 namespace vigir_step_control
00006 {
00007 StepQueue::StepQueue()
00008 {
00009 }
00010
00011 StepQueue::~StepQueue()
00012 {
00013 }
00014
00015 void StepQueue::reset()
00016 {
00017 UniqueLock lock(queue_mutex_);
00018 step_plan_.clear();
00019 is_dirty_ = true;
00020 }
00021
00022 bool StepQueue::empty() const
00023 {
00024 UniqueLock lock(queue_mutex_);
00025 return step_plan_.empty();
00026 }
00027
00028 size_t StepQueue::size() const
00029 {
00030 SharedLock lock(queue_mutex_);
00031 return step_plan_.size();
00032 }
00033
00034 bool StepQueue::isDirty() const
00035 {
00036 SharedLock lock(queue_mutex_);
00037 return is_dirty_;
00038 }
00039
00040 void StepQueue::clearDirtyFlag()
00041 {
00042 UniqueLock lock(queue_mutex_);
00043 is_dirty_ = false;
00044 }
00045
00046 bool StepQueue::updateStepPlan(const msgs::StepPlan& step_plan, int min_step_index)
00047 {
00048 if (step_plan.steps.empty())
00049 return true;
00050
00052 msgs::ErrorStatus status = isConsistent(step_plan);
00053 if (!isOk(status))
00054 {
00055 ROS_ERROR("[StepQueue] updateStepPlan: Consistency check failed!");
00056 ROS_ERROR("%s", toString(status).c_str());
00057 return false;
00058 }
00059
00060 unsigned int step_plan_start_index = std::max(min_step_index, step_plan.steps.front().step_index);
00061
00062 UniqueLock lock(queue_mutex_);
00063
00064
00065 if (this->step_plan_.empty())
00066 {
00067 if (step_plan_start_index != 0)
00068 {
00069 ROS_ERROR("[StepQueue] updateStepPlan: Current step queue is empty. Expected step plan starting with index 0!");
00070 return false;
00071 }
00072 }
00073 else
00074 {
00075 msgs::Step old_step;
00076 msgs::Step new_step;
00077
00078
00079 if (!this->step_plan_.getStep(old_step, step_plan_start_index))
00080 {
00081 ROS_ERROR("[StepQueue] updateStepPlan: Can't merge plan due to non-overlapping step indices of current step plan (max queued index: %i, needed index: %u)!", this->step_plan_.getLastStepIndex(), step_plan_start_index);
00082 return false;
00083 }
00084
00085 else if (!StepPlan::getStep(new_step, step_plan, step_plan_start_index))
00086 {
00087 ROS_ERROR("[StepQueue] updateStepPlan: Can't merge plan due to non-overlapping step indices of new step plan (max index: %u, needed index: %u)!", step_plan.steps.back().step_index, step_plan_start_index);
00088 return false;
00089 }
00090
00091 else if (old_step.foot.foot_index != new_step.foot.foot_index)
00092 {
00093 ROS_ERROR("[StepQueue] updateStepPlan: Step %u has wrong foot index!", step_plan_start_index);
00094 return false;
00095 }
00096
00097 else
00098 {
00099 geometry_msgs::Pose p_old = old_step.foot.pose;
00100 geometry_msgs::Pose p_new = new_step.foot.pose;
00101 if (p_old.position.x != p_new.position.x || p_old.position.y != p_new.position.y || p_old.position.z != p_new.position.z)
00102 {
00103 ROS_WARN("[StepQueue] updateStepPlan: Overlapping step differs in position! Delta: %f/%f/%f", p_new.position.x-p_old.position.x, p_new.position.y-p_old.position.y, p_new.position.z-p_old.position.z);
00104 }
00105 if (p_old.orientation.x != p_new.orientation.x || p_old.orientation.y != p_new.orientation.y || p_old.orientation.z != p_new.orientation.z || p_old.orientation.w != p_new.orientation.w)
00106 {
00107 ROS_WARN("[StepQueue] updateStepPlan: Overlapping step differs in orientation! Delta: %f/%f/%f/%f", p_new.orientation.x-p_old.orientation.x, p_new.orientation.y-p_old.orientation.y, p_new.orientation.z-p_old.orientation.z, p_new.orientation.w-p_old.orientation.w);
00108 }
00109 }
00110 }
00111
00113 status += this->step_plan_.stitchStepPlan(step_plan, step_plan_start_index);
00114 this->step_plan_.removeSteps(step_plan.steps.rbegin()->step_index+1);
00115
00116 is_dirty_ = true;
00117
00118 return isOk(status);
00119 }
00120
00121 bool StepQueue::getStep(msgs::Step& step, unsigned int step_index)
00122 {
00123 SharedLock lock(queue_mutex_);
00124 return step_plan_.getStep(step, step_index);
00125 }
00126
00127 bool StepQueue::getStepAt(msgs::Step& step, unsigned int position)
00128 {
00129 SharedLock lock(queue_mutex_);
00130 return step_plan_.getStepAt(step, position);
00131 }
00132
00133 std::vector<msgs::Step> StepQueue::getSteps(unsigned int start_index, unsigned int end_index) const
00134 {
00135 SharedLock lock(queue_mutex_);
00136
00137 std::vector<msgs::Step> steps;
00138
00139 for (unsigned int i = start_index; i <= end_index; i++)
00140 {
00141 msgs::Step step;
00142 if (step_plan_.getStep(step, i))
00143 steps.push_back(step);
00144 }
00145
00146 return steps;
00147 }
00148
00149 void StepQueue::removeStep(unsigned int step_index)
00150 {
00151 UniqueLock lock(queue_mutex_);
00152 step_plan_.removeStep(step_index);
00153 is_dirty_ = true;
00154 }
00155
00156 void StepQueue::removeSteps(unsigned int from_step_index, int to_step_index)
00157 {
00158 UniqueLock lock(queue_mutex_);
00159 step_plan_.removeSteps(from_step_index, to_step_index);
00160 is_dirty_ = true;
00161 }
00162
00163 bool StepQueue::popStep(msgs::Step& step)
00164 {
00165 UniqueLock lock(queue_mutex_);
00166 is_dirty_ = true;
00167 return step_plan_.popStep(step);
00168 }
00169
00170 bool StepQueue::popStep()
00171 {
00172 msgs::Step step;
00173 is_dirty_ = true;
00174 return popStep(step);
00175 }
00176
00177 int StepQueue::firstStepIndex() const
00178 {
00179 SharedLock lock(queue_mutex_);
00180
00181 msgs::Step step;
00182 if (step_plan_.getfirstStep(step))
00183 return step.step_index;
00184 else
00185 return -1;
00186 }
00187
00188 int StepQueue::lastStepIndex() const
00189 {
00190 SharedLock lock(queue_mutex_);
00191
00192 msgs::Step step;
00193 if (step_plan_.getLastStep(step))
00194 return step.step_index;
00195 else
00196 return -1;
00197 }
00198 }