OccupancyGrid.h
Go to the documentation of this file.
1#pragma once
2
3#include <boost/dynamic_bitset/dynamic_bitset.hpp>
4
5#include <Eigen/Core>
6#include <Eigen/Geometry>
7
8namespace armarx
9{
10
11 // https://stackoverflow.com/questions/9255887/stl-function-to-test-whether-a-value-is-within-some-range
12 template <typename T>
14 {
15 public:
16 Interval(T lo, T hi) : low(lo), high(hi)
17 {
18 }
19
20 bool
21 contains(T value) const
22 {
23 return low <= value && value < high;
24 }
25
26 private:
27 T low;
28 T high;
29 };
30
31 template <typename T>
32 Interval<T>
34 {
35 return Interval<T>(lo, hi);
36 }
37
39 {
40 void
41 init(std::size_t gridSizeX,
42 std::size_t gridSizeY,
43 float originX,
44 float originY,
45 float gridStepSize)
46 {
47 sizeX = gridSizeX;
48 sizeY = gridSizeY;
49 this->originX = originX;
50 this->originY = originY;
51 this->stepSize = gridStepSize;
52 std::size_t gridSize = sizeX * sizeY;
53 occupied.clear();
54 occupied.resize(gridSize);
55 }
56
57 bool
58 isOccupied(std::size_t indexX, std::size_t indexY) const
59 {
60 std::size_t index = indexY * sizeX + indexX;
61 if (index < occupied.size())
62 {
63 return occupied[index];
64 }
65 return false;
66 }
67
68 void
69 setOccupied(std::size_t indexX, std::size_t indexY, bool posOccupied)
70 {
71 std::size_t index = indexY * sizeX + indexX;
72 if (index < occupied.size())
73 {
74 occupied[index] = posOccupied;
75 }
76 }
77
78 Eigen::Vector2f
79 getCentralPosition(std::size_t indexX, std::size_t indexY) const
80 {
81 float posX = originX + indexX * stepSize;
82 float posY = originY + indexY * stepSize;
83 return Eigen::Vector2f(posX, posY);
84 }
85
86 bool
87 isOccupied(float posX, float posY) const
88 {
89 std::size_t indexX = (std::size_t)std::roundf((posX - originX) / stepSize);
90 std::size_t indexY = (std::size_t)std::roundf((posY - originY) / stepSize);
91 return isOccupied(indexX, indexY);
92 }
93
94 bool
95 isInBounds(float posX, float posY) const
96 {
97 const int indexX = static_cast<int>(std::roundf((posX - originX) / stepSize));
98 const int indexY = static_cast<int>(std::roundf((posY - originY) / stepSize));
99
100 return Interval<int>(0, sizeX).contains(indexX) &&
101 Interval<int>(0, sizeY).contains(indexY);
102 }
103
104 float
105 computeDistance(Eigen::Vector2f pos, Eigen::Vector2f dir)
106 {
107 // std::size_t indexX = (std::size_t)std::roundf((pos.x() - originX) / stepSize);
108 // std::size_t indexY = (std::size_t)std::roundf((pos.y() - originY) / stepSize);
109
110
111 // if (indexX >= sizeX || indexY >= sizeY)
112 // {
113 // return 0.0f;
114 // }
115
116 // We are inside the grid
117 // float gridMaxX = originX + stepSize * sizeX;
118 // float gridMaxY = originY + stepSize * sizeY;
119 // float distanceX = 0.0f;
120 // if (dir.x() > 0.0f)
121 // {
122 // distanceX = std::abs((gridMaxX - pos.x()) / dir.x());
123 // }
124 // else if (dir.x() < 0.0f)
125 // {
126 // distanceX = std::abs((pos.x() - originX) / dir.x());
127 // }
128 // float distanceY = 0.0f;
129 // if (dir.y() > 0.0f)
130 // {
131 // distanceY = std::abs((gridMaxY - pos.y()) / dir.y());
132 // }
133 // else if (dir.y() < 0.0f)
134 // {
135 // distanceY = std::abs((pos.y() - originY) / dir.y());
136 // }
137
138 // What is the max distance we can travel along dir until we leave the grid?
139 float maxDistance = 15'000; // TODO based on sensor specs
140 float testStepSize = 0.5f * stepSize;
141 Eigen::Vector2f testStep = testStepSize * dir;
142 std::size_t lineSteps = std::ceil(maxDistance / testStepSize);
143 for (std::size_t i = 0; i < lineSteps; ++i)
144 {
145 Eigen::Vector2f testPos = pos + i * testStep;
146 if (isInBounds(testPos.x(), testPos.y()) && isOccupied(testPos.x(), testPos.y()))
147 {
148 return i * testStepSize;
149 }
150 }
151
152 return -1.F;
153 }
154
155 std::size_t sizeX = 0;
156 std::size_t sizeY = 0;
157 float originX = 0.0f;
158 float originY = 0.0f;
159 float stepSize = 0.0f;
160 boost::dynamic_bitset<std::size_t> occupied;
161 };
162
163} // namespace armarx
#define lo(x)
#define hi(x)
uint8_t index
bool contains(T value) const
Interval(T lo, T hi)
This file offers overloads of toIce() and fromIce() functions for STL container types.
Interval< T > interval(T lo, T hi)
void setOccupied(std::size_t indexX, std::size_t indexY, bool posOccupied)
float computeDistance(Eigen::Vector2f pos, Eigen::Vector2f dir)
bool isOccupied(std::size_t indexX, std::size_t indexY) const
bool isInBounds(float posX, float posY) const
bool isOccupied(float posX, float posY) const
boost::dynamic_bitset< std::size_t > occupied
Eigen::Vector2f getCentralPosition(std::size_t indexX, std::size_t indexY) const
void init(std::size_t gridSizeX, std::size_t gridSizeY, float originX, float originY, float gridStepSize)