NavMap
Loading...
Searching...
No Matches
Occupancy.hpp
Go to the documentation of this file.
1// Copyright 2026 Intelligent Robotics Lab
2//
3// This file is part of the project Easy Navigation (EasyNav in short)
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
24
25#ifndef NAVMAP_CORE__OCCUPANCY_HPP_
26#define NAVMAP_CORE__OCCUPANCY_HPP_
27
28#include <algorithm>
29#include <cmath>
30#include <cstdint>
31#include <limits>
32#include <memory>
33#include <string>
34
36
37namespace navmap
38{
39
42{
43 float p_hit{0.7f};
44 float p_miss{0.4f};
45 float p_min{0.12f};
46 float p_max{0.97f};
47 float p_occupied{0.6f};
48 float p_free{0.4f};
49};
50
52enum class OccupancyState : uint8_t { UNKNOWN = 0, FREE = 1, OCCUPIED = 2 };
53
61{
62public:
63 static constexpr float kScale = 1000.0f;
64
65 static int16_t to_fixed(float logodds)
66 {
67 const float v = std::round(logodds * kScale);
68 return static_cast<int16_t>(std::clamp(v, -32767.0f, 32767.0f));
69 }
70 static float logodds_of(float p) {return std::log(p / (1.0f - p));}
71 static float probability_of(float logodds) {return 1.0f / (1.0f + std::exp(-logodds));}
72
75 NavMap & nm, const std::string & name = "occupancy_logodds", OccupancyParams p = {})
76 : name_(name),
77 hit_(to_fixed(logodds_of(p.p_hit))), miss_(to_fixed(logodds_of(p.p_miss))),
78 min_(to_fixed(logodds_of(p.p_min))), max_(to_fixed(logodds_of(p.p_max))),
79 occ_(to_fixed(logodds_of(p.p_occupied))), free_(to_fixed(logodds_of(p.p_free)))
80 {
81 const bool existed = nm.has_layer(name);
82 view_ = nm.add_layer<int16_t>(name, "occupancy log-odds", "1/1000 log-odds", 0);
83 if (!existed) {nm.set_layer_unknown(name, 0.0);}
84 }
85
87 void hit(NavCelId cid) {add(cid, hit_);}
89 void miss(NavCelId cid) {add(cid, miss_);}
90 void update(NavCelId cid, bool occupied) {add(cid, occupied ? hit_ : miss_);}
91
93 void add(NavCelId cid, int16_t delta)
94 {
95 auto & d = view_->data();
96 if (cid >= d.size()) {return;}
97 const int v = static_cast<int>(d[cid]) + delta;
98 d[cid] = static_cast<int16_t>(std::clamp(v, static_cast<int>(min_), static_cast<int>(max_)));
99 view_->mark_changed(cid);
100 }
101
103 void reset(NavCelId cid)
104 {
105 auto & d = view_->data();
106 if (cid < d.size()) {d[cid] = 0; view_->mark_changed(cid);}
107 }
108
109 float logodds(NavCelId cid) const {return value(cid) / kScale;}
110 float probability(NavCelId cid) const {return probability_of(logodds(cid));}
111
113 {
114 const int16_t v = value(cid);
115 if (v >= occ_) {return OccupancyState::OCCUPIED;}
116 if (v <= free_) {return OccupancyState::FREE;}
118 }
119
120 const std::string & name() const {return name_;}
121 const std::shared_ptr<LayerView<int16_t>> & view() const {return view_;}
122
123private:
124 int16_t value(NavCelId cid) const
125 {
126 const auto & d = view_->data();
127 return cid < d.size() ? d[cid] : int16_t{0};
128 }
129
130 std::string name_;
131 std::shared_ptr<LayerView<int16_t>> view_;
132 int16_t hit_, miss_, min_, max_, occ_, free_;
133};
134
135} // namespace navmap
136
137#endif // NAVMAP_CORE__OCCUPANCY_HPP_
Core container and data structures for EasyNav navigable meshes.
Definition NavMap.hpp:561
std::shared_ptr< LayerView< T > > add_layer(const std::string &name, const std::string &description={}, const std::string &unit={}, T default_value=T{})
Create (or get) a typed per-NavCel layer with a default value.
Definition NavMap.hpp:877
void set_layer_unknown(const std::string &name, double value)
Declare the value of layer name that means "not observed" (NaN allowed).
Definition NavMap.cpp:1353
bool has_layer(const std::string &name) const
Check whether a layer named name exists.
Definition NavMap.cpp:1321
static float probability_of(float logodds)
Definition Occupancy.hpp:71
const std::string & name() const
Definition Occupancy.hpp:120
void update(NavCelId cid, bool occupied)
Definition Occupancy.hpp:90
float probability(NavCelId cid) const
Definition Occupancy.hpp:110
OccupancyLayer(NavMap &nm, const std::string &name="occupancy_logodds", OccupancyParams p={})
Uses (or creates, all unknown) the int16 layer name of nm.
Definition Occupancy.hpp:74
static int16_t to_fixed(float logodds)
Definition Occupancy.hpp:65
void miss(NavCelId cid)
A measurement crossed cid (free evidence).
Definition Occupancy.hpp:89
static constexpr float kScale
int16 units per log-odds unit
Definition Occupancy.hpp:63
void reset(NavCelId cid)
Forgets cid (back to unknown).
Definition Occupancy.hpp:103
static float logodds_of(float p)
Definition Occupancy.hpp:70
const std::shared_ptr< LayerView< int16_t > > & view() const
Definition Occupancy.hpp:121
float logodds(NavCelId cid) const
Definition Occupancy.hpp:109
void add(NavCelId cid, int16_t delta)
Adds delta (fixed point) to cid and clamps to [p_min, p_max].
Definition Occupancy.hpp:93
void hit(NavCelId cid)
A measurement ended in cid (occupied evidence).
Definition Occupancy.hpp:87
OccupancyState state(NavCelId cid) const
Definition Occupancy.hpp:112
Definition Combine.hpp:39
uint32_t NavCelId
Index of a triangle (NavCel) within the global mesh.
Definition NavMap.hpp:59
OccupancyState
Three-state classification of a NavCel.
Definition Occupancy.hpp:52
@ UNKNOWN
Definition Occupancy.hpp:52
@ FREE
Definition Occupancy.hpp:52
@ OCCUPIED
Definition Occupancy.hpp:52
Probabilities of the update rule and of the classification (OctoMap defaults).
Definition Occupancy.hpp:42
float p_max
Clamping: never more certain of occupied than this.
Definition Occupancy.hpp:46
float p_hit
A measurement ends in the NavCel.
Definition Occupancy.hpp:43
float p_occupied
At or above: OCCUPIED.
Definition Occupancy.hpp:47
float p_miss
A measurement crosses the NavCel.
Definition Occupancy.hpp:44
float p_min
Clamping: never more certain of free than this.
Definition Occupancy.hpp:45
float p_free
At or below: FREE (in between: UNKNOWN).
Definition Occupancy.hpp:48