30 const
unsigned int INVALID_K =
std::numeric_limits<
unsigned int>::max();
35 m_last_selected_sector (
std::numeric_limits<
unsigned int>::max() )
38 initialize( *INI_FILE );
43 options.saveToConfigFile(
c, getConfigFileSectionName());
48 options.loadFromConfigFile(
c, getConfigFileSectionName());
60 min_eval(
std::numeric_limits<double>::max()),
61 max_eval(-
std::numeric_limits<double>::max()),
62 contains_target_k(false),
67 CHolonomicFullEval::EvalOutput::EvalOutput() :
77 const auto target = ni.
targets[target_idx];
84 const double ptg_ref_dist = ptg ? ptg->getRefDistance() : 1.0;
87 const double target_dir = ::atan2(target.y, target.x);
89 const double target_dist = target.norm();
94 std::vector<mrpt::math::TPoint2D> obstacles_2d(nDirs);
102 for (
unsigned int i=0;i<nDirs;i++)
104 obstacles_2d[i].x = ni.
obstacles[i] * sc_lut.ccos[i];
105 obstacles_2d[i].y = ni.
obstacles[i] * sc_lut.csin[i];
108 const int NUM_FACTORS = 5;
112 for (
unsigned int i=0;i<nDirs;i++)
114 double scores[NUM_FACTORS];
125 const double x = d*sc_lut.ccos[i];
126 const double y = d*sc_lut.csin[i];
133 scores[0] = std::max(target_dist,ni.
obstacles[i]) / (target_dist*1.05);
142 const double max_real_freespace = ptg->getActualUnloopedPathLength(i);
143 const double max_real_freespace_norm = max_real_freespace / ptg->getRefDistance();
157 double min_dist_target_along_path = sg.
distance(target);
161 const double endpt_dist_to_target = (target -
TPoint2D(
x,
y)).
norm();
162 const double endpt_dist_to_target_norm =
std::min(1.0, endpt_dist_to_target);
165 (endpt_dist_to_target_norm > target_dist && endpt_dist_to_target_norm >= 0.95 * target_dist)
166 && min_dist_target_along_path > 1.05 *
std::min(target_dist, endpt_dist_to_target_norm)
173 min_dist_target_along_path = sg.
distance(target);
176 scores[1] = 1.0 / (1.0 +
square(min_dist_target_along_path) );
181 scores[2] = std::sqrt(1.01 - endpt_dist_to_target_norm);
192 else scores[3] = 1.0;
201 const double query_dist_norm =
std::min(0.99, target_dist*0.95);
204 scores[4] = 0.5* (avr_path_clearance + point_clearance);
208 for (
int l=0;l<NUM_FACTORS;l++)
m_dirs_scores(i,l)= scores[l];
213 for (
int l = 0; l < NUM_FACTORS; l++)
220 if (
span <= .0)
continue;
231 std::vector<double> weights_sum_phase(NUM_PHASES, .0), weights_sum_phase_inv(NUM_PHASES);
232 for (
unsigned int i = 0; i < NUM_PHASES; i++)
235 ASSERT_(weights_sum_phase[i]>.0);
236 weights_sum_phase_inv[i] = 1.0 / weights_sum_phase[i];
239 eo.
phase_scores = std::vector<std::vector<double> >(NUM_PHASES, std::vector<double>(nDirs,.0) );
241 double last_phase_threshold = -1.0;
243 for (
unsigned int phase_idx = 0; phase_idx < NUM_PHASES; phase_idx++)
245 double phase_min = std::numeric_limits<double>::max(), phase_max = .0;
247 for (
unsigned int i = 0; i < nDirs; i++)
249 double this_dir_eval = 0;
252 (phase_idx>0 && phase_scores[phase_idx-1][i]<last_phase_threshold)
263 this_dir_eval *= weights_sum_phase_inv[phase_idx];
264 this_dir_eval = std::exp(this_dir_eval);
266 phase_scores[phase_idx][i] = this_dir_eval;
280 auto & dirs_eval = *phase_scores.rbegin();
286 double phase_min = std::numeric_limits<double>::max(), phase_max = .0;
287 for (
unsigned int i = 0; i < nDirs; i++)
300 std::vector<TGap> gaps;
301 int best_gap_idx = -1;
302 int gap_idx_for_target_dir = -1;
304 bool inside_gap =
false;
305 for (
unsigned int i = 0; i < nDirs; i++)
307 const double val = dirs_eval[i];
308 if (
val < last_phase_threshold)
313 auto &active_gap = *gaps.rbegin();
314 active_gap.k_to = i - 1;
326 gaps.emplace_back(new_gap);
333 auto &active_gap = *gaps.rbegin();
334 if (
val >= active_gap.max_eval) {
335 active_gap.k_best_eval = i;
341 active_gap.contains_target_k =
true;
342 gap_idx_for_target_dir = gaps.size() - 1;
345 if (best_gap_idx == -1 ||
val > gaps[best_gap_idx].max_eval) {
346 best_gap_idx = gaps.size()-1;
353 auto &active_gap = *gaps.rbegin();
354 active_gap.k_to = nDirs - 1;
359 ASSERT_(best_gap_idx>=0 && best_gap_idx<
int(gaps.size()));
361 const TGap & best_gap = gaps[best_gap_idx];
366 if (best_gap_idx == gap_idx_for_target_dir)
372 const auto smallest_clearance_in_k_units =
std::min(cl_left, cl_right);
375 const unsigned int gap_width = best_gap.
k_to - best_gap.
k_from;
379 if (smallest_clearance_in_k_units >= clearance_threshold &&
380 gap_width>=width_threshold &&
398 if (target_dist<0.99 &&
401 ( ni.
obstacles[target_k]>target_dist*1.01 &&
407 ( ni.
obstacles[target_k]>(target_dist+0.15 /ptg_ref_dist) &&
408 target_dist<(1.5 / ptg_ref_dist)
412 dirs_eval[target_k]>0
419 phase_scores[NUM_PHASES - 1][target_k] += 2.0;
435 const size_t numTrgs = ni.
targets.size();
437 std::vector<EvalOutput> evals(numTrgs);
438 double best_eval = .0;
439 unsigned int best_trg_idx = 0;
441 for (
unsigned int trg_idx = 0; trg_idx < numTrgs; trg_idx++)
443 auto & eo = evals[trg_idx];
446 if (eo.best_eval >= best_eval)
448 best_eval = eo.best_eval;
449 best_trg_idx = trg_idx;
464 const double ptg_ref_dist = ptg ? ptg->getRefDistance() : 1.0;
475 const double obs_dist = ni.
obstacles[evals[best_trg_idx].best_k];
477 double riskFactor = 1.0;
493 log->selectedTarget = best_trg_idx;
494 log->selectedSector = evals[best_trg_idx].best_k;
495 log->evaluation = evals[best_trg_idx].best_eval;
496 log->dirs_eval = evals[best_trg_idx].phase_scores;
509 else return static_cast<unsigned int>(idx);
572 TOO_CLOSE_OBSTACLE ( 0.15 ),
573 TARGET_SLOW_APPROACHING_DISTANCE ( 0.60 ),
574 OBSTACLE_SLOW_DOWN_DISTANCE ( 0.15 ),
575 HYSTERESIS_SECTOR_COUNT ( 5 ),
576 LOG_SCORE_MATRIX(false),
577 clearance_threshold_ratio(0.05),
578 gap_width_ratio_threshold(0.25)
580 factorWeights = mrpt::math::make_vector<5,double>(0.1 , 0.5 , 0.5 , 0.01 , 1 );
604 c.read_vector(
s,
"factorWeights", std::vector<double>(), factorWeights,
true );
605 ASSERT_(factorWeights.size()==5);
607 c.read_vector(
s,
"factorNormalizeOrNot", factorNormalizeOrNot, factorNormalizeOrNot);
608 ASSERT_(factorNormalizeOrNot.size() == factorWeights.size());
614 PHASE_FACTORS.resize(PHASE_COUNT);
615 PHASE_THRESHOLDS.resize(PHASE_COUNT);
616 for (
int i = 0; i < PHASE_COUNT; i++)
618 c.read_vector(
s,
mrpt::format(
"PHASE%i_FACTORS",i + 1), PHASE_FACTORS[i], PHASE_FACTORS[i],
true);
621 PHASE_THRESHOLDS[i] =
c.read_double(
s,
mrpt::format(
"PHASE%i_THRESHOLD", i + 1),.0,
true);
622 ASSERT_(PHASE_THRESHOLDS[i]>=.0 && PHASE_THRESHOLDS[i]<=1.0);
636 MRPT_SAVE_CONFIG_VAR_COMMENT(OBSTACLE_SLOW_DOWN_DISTANCE,
"Start to reduce speed when clearance is below this value ([0,1] ratio wrt obstacle reference/max distance)");
639 MRPT_SAVE_CONFIG_VAR_COMMENT(clearance_threshold_ratio,
"Ratio [0,1], times path_count, gives the minimum number of paths at each side of a target direction to be accepted as desired direction");
640 MRPT_SAVE_CONFIG_VAR_COMMENT(gap_width_ratio_threshold,
"Ratio [0,1], times path_count, gives the minimum gap width to accept a direct motion towards target.");
643 c.write(
s,
"factorWeights",
mrpt::system::sprintf_container(
"%.2f ",factorWeights), WN,WV,
"[0]=Free space, [1]=Dist. in sectors, [2]=Closer to target (Euclidean), [3]=Hysteresis, [4]=clearance along path");
646 c.write(
s,
"PHASE_COUNT", PHASE_FACTORS.size(), WN, WV,
"Number of evaluation phases to run (params for each phase below)");
648 for (
unsigned int i = 0; i < PHASE_FACTORS.size(); i++)
650 c.write(
s,
mrpt::format(
"PHASE%u_THRESHOLD", i + 1), PHASE_THRESHOLDS[i], WN, WV,
"Phase scores must be above this relative range threshold [0,1] to be considered in next phase (Default:`0.75`)");
#define ASSERT_EQUAL_(__A, __B)
double index2alpha(uint16_t k) const
Alpha value for the discrete corresponding value.
unsigned int direction2sector(const double a, const unsigned int N)
int BASE_IMPEXP MRPT_SAVE_VALUE_PADDING
Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
double gap_width_ratio_threshold
Ratio [0,1], times path_count, gives the minimum gap width to accept a direct motion towards target...
virtual void postProcessDirectionEvaluations(std::vector< double > &dir_evals, const NavInput &ni, unsigned int trg_idx)
int k_best_eval
Direction with the best evaluation inside the gap.
mrpt::obs::CSinCosLookUpTableFor2DScans m_sincos_lut
EIGEN_STRONG_INLINE bool empty() const
void navigate(const NavInput &ni, NavOutput &no) MRPT_OVERRIDE
Invokes the holonomic navigation algorithm itself.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
A class for storing extra information about the execution of CHolonomicFullEval navigation.
const TSinCosValues & getSinCosForScan(const CObservation2DRangeScan &scan) const
Return two vectors with the cos and the sin of the angles for each of the rays in a scan...
double TOO_CLOSE_OBSTACLE
Directions with collision-free distances below this threshold are not elegible.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define MRPT_LOAD_CONFIG_VAR_NO_DEFAULT(variableName, variableType, configFileObject, sectionNameStr)
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
double distance(const TPoint2D &point) const
Distance to point.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
This file implements several operations that operate element-wise on individual or pairs of container...
A base class for holonomic reactive navigation methods.
double TARGET_SLOW_APPROACHING_DISTANCE
Start to reduce speed when closer than this to target [m].
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string §ion) const MRPT_OVERRIDE
This method saves the options to a ".ini"-like file or memory-stored string list. ...
int32_t selectedTarget
Normally = 0. Can be >0 if multiple targets passed simultaneously.
std::vector< int32_t > factorNormalizeOrNot
0/1 to normalize factors.
bool m_enableApproachTargetSlowDown
Whether to decrease speed when approaching target.
double clearance_threshold_ratio
Ratio [0,1], times path_count, gives the minimum number of paths at each side of a target direction t...
CLogFileRecord_FullEval()
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
std::vector< double > PHASE_THRESHOLDS
Phase 1,2,N-1... scores must be above this relative range threshold [0,1] to be considered in phase 2...
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
TOptions options
Parameters of the algorithm (can be set manually or loaded from CHolonomicFullEval::initialize or opt...
double OBSTACLE_SLOW_DOWN_DISTANCE
Start to reduce speed when clearance is below this value ([0,1] ratio wrt obstacle reference/max dist...
double getClearance(uint16_t k, double TPS_query_distance, bool integrate_over_path) const
Gets the clearance for path k and distance TPS_query_distance in one of two modes: ...
int mmin(const int t1, const int t2)
int32_t selectedSector
Member data.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
const unsigned int INVALID_K
This base provides a set of functions for maths stuff.
2D segment, consisting of two points.
#define MRPT_SAVE_CONFIG_VAR_COMMENT(variableName, __comment)
Auxiliary struct that holds all the relevant geometry information about a 2D scan.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
A base class for log records for different holonomic navigation methods.
double desiredDirection
The desired motion direction, in the range [-PI, PI].
std::vector< double > factorWeights
See docs above.
void evalSingleTarget(unsigned int target_idx, const NavInput &ni, EvalOutput &eo)
Evals one single target of the potentially many of them in NavInput.
TPoint2D point2
Destiny point.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLsizei const GLchar ** string
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Full evaluation of all possible directions within the discrete set of input directions.
std::vector< std::vector< double > > dirs_eval
Final [N-1] and earlier stages [0...N-1] evaluation scores for each direction, in the same order of T...
TPoint2D point1
Origin point.
double desiredSpeed
The desired motion speed in that direction, from 0 up to NavInput::maxRobotSpeed. ...
static CLogFileRecord_FullEvalPtr Create()
#define MRPT_LOAD_CONFIG_VAR(variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::math::CMatrixD m_dirs_scores
Individual scores for each direction: (i,j), i (row) are directions, j (cols) are scores...
T square(const T x)
Inline function for the square of a number.
double HYSTERESIS_SECTOR_COUNT
Range of "sectors" (directions) for hysteresis over successive timesteps.
int round(const T value)
Returns the closer integer (int) to x.
unsigned int m_last_selected_sector
T abs_diff(const T a, const T b)
Efficient and portable evaluation of the absolute difference of two unsigned integer values (but will...
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
bool rightToLeft
Angles storage order: true=counterclockwise; false=clockwise.
GLenum GLenum GLvoid GLvoid GLvoid * span
GLubyte GLubyte GLubyte a
Output for CAbstractHolonomicReactiveMethod::navigate()
mrpt::math::CMatrixD dirs_scores
Individual scores for each direction: (i,j), i (row) are directions, j (cols) are scores...
std::string sprintf_container(const char *fmt, const T &V)
Generates a string for a container in the format [A,B,C,...], and the fmt string for each vector elem...
std::vector< std::vector< double > > phase_scores
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
mrpt::nav::CParameterizedTrajectoryGenerator * getAssociatedPTG() const
Returns the pointer set by setAssociatedPTG()
std::vector< std::vector< int32_t > > PHASE_FACTORS
Factor indices [0,4] for the factors to consider in each phase 1,2,...N of the movement decision (Def...
bool LOG_SCORE_MATRIX
(default:false, to save space)
int BASE_IMPEXP MRPT_SAVE_NAME_PADDING
uint16_t alpha2index(double alpha) const
Discrete index value for the corresponding alpha value.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
CONTAINER::Scalar norm(const CONTAINER &v)
CHolonomicLogFileRecordPtr logRecord
The navigation method will create a log record and store it here via a smart pointer.