Galaxis Codebase  1.0.0
Team Galaxis software stack for the Carolo Cup 2023 - ROS2 based software
MapDataLayer.cpp
Go to the documentation of this file.
2 
4 
5 #include <cassert>
6 
7 #include <utils/logger.hpp>
8 
9 #include <cmath>
10 
11 
12 using namespace galaxis::utils;
13 
14 using namespace galaxis::map::data;
15 
16 MapDataLayer::MapDataLayer(int amountOfThreads = 4) :
17  m_threadPool(amountOfThreads), m_amountOfThreads(amountOfThreads) {
18  assert(m_amountOfThreads > 0);
19  init();
20 }
21 
23  m_threadPool(4) {
25  init();
26 }
27 
29  m_threadPool.join();
30 }
31 
32 void MapDataLayer::init() {
33  log("MapDataLayer:\n - Threads: ", m_amountOfThreads, "\n - Map Size: ", MAP_SIZE, "x", MAP_SIZE);
34 
37 
38  m_linesObjectSPtr = std::make_shared<LinesObject<int16_t>>();
39 
40  clear();
41 }
42 
43 void MapDataLayer::clear() {
44  for(ColumnMapArray& columnArray: m_data) {
45  columnArray.fill(MapCell());
46  }
47 }
48 
49 void MapDataLayer::updateMap(visualization_msgs::msg::Marker::SharedPtr laneDetectionSPtr, char laneType) {
50  // single-threaded
51  m_mapMutex.lock();
52 
53  bool usable = false;
54  geometry_msgs::msg::Point* lastPoint;
55 
56  if (laneType == 'l') {
58  lastPoint = &m_lastPointLeftLane;
59  }
60  else if (laneType == 'c') {
62  lastPoint = &m_lastPointCenterLane;
63  }
64  else if (laneType == 'r') {
66  lastPoint = &m_lastPointRightLane;
67  }
68 
69  for(geometry_msgs::msg::Point& point : laneDetectionSPtr->points) {
70  if (usable == false) {
71  lastPoint = &point;
72  usable = true;
73  continue;
74  }
75 
76  // approximate between points in 1cm steps
77  double distanceCM = sqrt((point.x - lastPoint->x)*(point.x - lastPoint->x) + (point.y - lastPoint->y)*(point.y - lastPoint->y)) * 100;
78  if (distanceCM <= 1) {
79  distanceCM = 1;
80  // log_warning("Fix distanceCM.");
81  }
82 
83  double distanceX = lastPoint->x - point.x; // in meter
84  double distanceY = lastPoint->y - point.y; // in meter
85  for (double p = 0; p < 1; p += 1/distanceCM) {
86  double pointX = point.x + p * distanceX;
87  double pointY = point.y + p * distanceY;
88  pointX *= 100; // to CM
89  pointY *= 100; // to CM
90 
91  Vector2i absoluteCellPositionOnGrid = Vector2i(std::round(pointX), std::round(pointY));
92  absoluteCellPositionOnGrid[0] += static_cast<int>(m_absoluteCarPositionOffset[0]);
93  absoluteCellPositionOnGrid[1] += static_cast<int>(m_absoluteCarPositionOffset[1]);
94 
95  updateCell(absoluteCellPositionOnGrid, laneType);
96  }
97 
98  lastPoint = &point;
99  }
100 
101  if (laneType == 'l') {
102  m_lastPointLeftLane = *lastPoint;
104  }
105  else if (laneType == 'c') {
106  m_lastPointCenterLane = *lastPoint;
108  }
109  else if (laneType == 'r') {
110  m_lastPointRightLane = *lastPoint;
112  }
113  m_mapMutex.unlock();
114 }
115 
116 void MapDataLayer::updateCell(Vector2i position, char laneType) {
117  if(position[0] < 0 || position[0] >= m_mapSize[0] || position[1] < 0 || position[1] >= m_mapSize[1]) {
118  log_warning("MapDataLayer::updateCell: cannot update Cell (out of bounds) at Position (", position[0], ",", position[1], ")");
119  return;
120  }
121 
122  MapCell* cellPtr = &m_data[position[0]][position[1]];
123  if (laneType == 'l')
124  cellPtr->leftLine = true;
125  else if (laneType == 'c')
126  cellPtr->centerLine = true;
127  else if (laneType == 'r')
128  cellPtr->rightLine = true;
129  else
130  log_warning("Failure to updateMap. Wrong lanetype parameter value (l,c,r)");
131 }
132 
133 std::shared_ptr<LinesObject<int16_t>> MapDataLayer::getLineObject(Vector2f absolutePositionCM, float absoluteOrientation, Vector2i windowSize, Vector2i& effectiveWindowSize) {
134  m_mapMutex.lock();
135 
136  // Eigen rotates COUNTER-clock wise!
137  Eigen::Rotation2Df rotationMatrix(-absoluteOrientation);
138  Eigen::Rotation2Df reverseRotationMatrix(absoluteOrientation);
139 
140  m_linesObjectSPtr->clear();
141  m_linesObjectSPtr->rotationMatrix = rotationMatrix;
142  m_linesObjectSPtr->reverseRotationMatrix = reverseRotationMatrix;
143 
144  absolutePositionCM += m_absoluteCarPositionOffset;
145  Vector2i absolutePositionInteger = Vector2i(std::round(absolutePositionCM[0]), std::round(absolutePositionCM[1]));
146 
147  // put larger rectangle above window for map iteration
148  Vector2f marginX = Vector2f(windowSize[0] / 2, 0);
149  Vector2f marginY = Vector2f(0, windowSize[1]);
150  marginX = rotationMatrix * marginX;
151  marginY = rotationMatrix * marginY;
152 
153  std::array<Vector2f, 4> windowEdges;
154  windowEdges[0] = absolutePositionCM - marginX;
155  windowEdges[1] = absolutePositionCM + marginX;
156  windowEdges[2] = windowEdges[0] + marginY;
157  windowEdges[3] = windowEdges[1] + marginY;
158 
159  Vector2i largerWindowBottomLeftCorner = Vector2i(std::round(map::utils::getMin(windowEdges, 0)), std::round(map::utils::getMin(windowEdges, 1)));
160  Vector2i largerWindowTopRightCorner = Vector2i(std::round(map::utils::getMax(windowEdges, 0)), std::round(map::utils::getMax(windowEdges, 1)));
161 
162  // check if lookup (axis aligned) window (larger window) inside of map
163  if(largerWindowBottomLeftCorner[0] < 0) {
164  log_warning("MapDataLayer::getLineObject: lookup (axis aligned) window size out of map size (X smaller than 0)");
165  largerWindowBottomLeftCorner[1] = 0;
166  }
167  if(largerWindowTopRightCorner[0] >= m_mapSize[0]) {
168  log_warning("MapDataLayer::getLineObject: lookup (axis aligned) window size out of map size (X larger than map)");
169  largerWindowTopRightCorner[0] = m_mapSize[0] - 1;
170  }
171  if(largerWindowBottomLeftCorner[1] < 0) {
172  log_warning("MapDataLayer::getLineObject: lookup (axis aligned) window size out of map size (Y smaller than 0)");
173  largerWindowBottomLeftCorner[1] = 0;
174  }
175  if(largerWindowTopRightCorner[1] >= m_mapSize[1]) {
176  log_warning("MapDataLayer::getLineObject: lookup (axis aligned) window size out of map size (Y larger than map)");
177  largerWindowTopRightCorner[1] = m_mapSize[1] - 1;
178  }
179 
180  // int largerWindowStepsPerThread = (largerWindowTopRightCorner[0] - largerWindowBottomLeftCorner[0]) / m_amountOfThreads;
181 
182  // assert(largerWindowStepsPerThread > 0);
183 
184  // int arrayStartX = largerWindowBottomLeftCorner[0];
185  // int arrayEndX = arrayStartX + largerWindowStepsPerThread;
186  // int arrayStartY = largerWindowBottomLeftCorner[1];
187  // int arrayEndY = largerWindowTopRightCorner[1];
188 
189  // for(int i = 0; i < m_amountOfThreads; ++i) {
190  // if(i == m_amountOfThreads - 1) {
191  // arrayEndX = largerWindowTopRightCorner[0] + 1;
192  // } else {
193  // arrayEndX = arrayStartX + largerWindowStepsPerThread;
194  // }
195 
196  // boost::asio::post(m_threadPool, std::bind(&MapDataLayer::iterateThroughMap, this, arrayStartX, arrayEndX, arrayStartY, arrayEndY, absolutePositionInteger));
197  // arrayStartX = arrayEndX;
198  // }
199 
200  iterateThroughMap(largerWindowBottomLeftCorner[0], largerWindowTopRightCorner[0] + 1, largerWindowBottomLeftCorner[1], largerWindowTopRightCorner[1], absolutePositionInteger);
201 
202  // m_threadPool.wait();
203  m_mapMutex.unlock();
204 
205  effectiveWindowSize[0] = largerWindowTopRightCorner[0] - largerWindowBottomLeftCorner[0];
206  assert(effectiveWindowSize[0] >= 0);
207  effectiveWindowSize[1] = largerWindowTopRightCorner[1] - largerWindowBottomLeftCorner[1];
208  assert(effectiveWindowSize[1] >= 0);
209 
210  return m_linesObjectSPtr;
211 }
212 
213 void MapDataLayer::iterateThroughMap(int arrayStartX, int arrayEndX, int arrayStartY, int arrayEndY, Vector2i const& absoluteCarPosition) {
214  MapCell const* cellPtr = nullptr;
215  for(int x = arrayStartX; x < arrayEndX; ++x) {
216  for(int y = arrayStartY; y <= arrayEndY; ++y) {
217  // append cell information to linesObject
218  cellPtr = &m_data[x][y];
219 
220  if(cellPtr->leftLine) {
221  m_linesObjectSPtr->leftLine.insert(x - absoluteCarPosition[0], y - absoluteCarPosition[1]);
222  }
223  if(cellPtr->centerLine) {
224  m_linesObjectSPtr->centerLine.insert(x - absoluteCarPosition[0], y - absoluteCarPosition[1]);
225  }
226  if(cellPtr->rightLine) {
227  m_linesObjectSPtr->rightLine.insert(x - absoluteCarPosition[0], y - absoluteCarPosition[1]);
228  }
229  }
230  }
231 }
MapDataLayer::m_lastPointCenterLane
geometry_msgs::msg::Point m_lastPointCenterLane
Definition: MapDataLayer.hpp:49
MapDataLayer::m_amountOfThreads
int m_amountOfThreads
Definition: MapDataLayer.hpp:63
MapDataLayer::~MapDataLayer
~MapDataLayer()
Definition: MapDataLayer.cpp:24
MapDataLayer::iterateThroughMap
void iterateThroughMap(int arrayStartX, int arrayEndX, int arrayStartY, int arrayEndY, Vector2i const &absoluteCarPosition, std::array< Vector2f, 4 > const &windowEdges)
Definition: MapDataLayer.cpp:334
MapCell::centerLine
uint8_t centerLine
Definition: MapDataLayer.hpp:47
MapDataLayer.hpp
galaxis::utils::log_warning
void log_warning(const Args &... args)
Definition: logger.hpp:41
MapDataLayer::m_lastPointLeftLaneUsable
bool m_lastPointLeftLaneUsable
Definition: MapDataLayer.hpp:48
MapDataLayer::clear
void clear()
Definition: MapDataLayer.cpp:41
MapDataLayer::getLineObject
std::shared_ptr< LinesObject< int16_t > > getLineObject(Vector2f absolutePositionCM, float lookBehindPosOffsetCM, double absoluteOrientation, Vector2i windowSize)
Definition: MapDataLayer.cpp:250
MapDataLayer::m_lastPointCenterLaneUsable
bool m_lastPointCenterLaneUsable
Definition: MapDataLayer.hpp:50
MapDataLayer::updateCell
void updateCell(MapCell const &cellUpdate, Vector2i position)
Definition: MapDataLayer.cpp:181
MapDataLayer::m_mapSize
Vector2f m_mapSize
Definition: MapDataLayer.hpp:68
map::utils::getMin
float getMin(std::array< galaxis::lina::Vector2f, 4 > const &array, int index)
Definition: MapUtils.hpp:10
MapDataLayer::updateMap
void updateMap(const sensor_msgs::msg::Image::ConstSharedPtr &laneDetectionSPtr, Vector2f currentAbsoluteCarPositionCM, double currentAbsoluteOrientation)
Definition: MapDataLayer.cpp:83
MapDataLayer::m_lastPointRightLane
geometry_msgs::msg::Point m_lastPointRightLane
Definition: MapDataLayer.hpp:51
MapCell::leftLine
uint8_t leftLine
Definition: MapDataLayer.hpp:46
MapCell::rightLine
uint8_t rightLine
Definition: MapDataLayer.hpp:48
MapDataLayer::MapDataLayer
MapDataLayer()
Definition: MapDataLayer.cpp:18
map::utils::getMax
float getMax(std::array< galaxis::lina::Vector2f, 4 > const &array, int index)
Definition: MapUtils.hpp:20
MapDataLayer::m_data
MapArray m_data
Definition: MapDataLayer.hpp:67
MapDataLayer::m_linesObjectSPtr
std::shared_ptr< LinesObject< int16_t > > m_linesObjectSPtr
Definition: MapDataLayer.hpp:74
MapUtils.hpp
MapDataLayer::m_absoluteCarPositionOffset
Vector2f m_absoluteCarPositionOffset
Definition: MapDataLayer.hpp:72
MapCell
Definition: MapDataLayer.hpp:45
MAP_SIZE
constexpr int MAP_SIZE
Definition: MapDataLayer.hpp:53
galaxis::lina::Vector2f
Eigen::Vector2f Vector2f
Definition: linatypes.hpp:14
MapDataLayer::m_mapMutex
std::mutex m_mapMutex
Definition: MapDataLayer.hpp:69
MapDataLayer::m_lastPointLeftLane
geometry_msgs::msg::Point m_lastPointLeftLane
Definition: MapDataLayer.hpp:47
galaxis::map::data
Definition: MapClasses.hpp:11
MapDataLayer::ColumnMapArray
std::array< MapCell, MAP_SIZE > ColumnMapArray
Definition: MapDataLayer.hpp:56
logger.hpp
MapDataLayer::m_lastPointRightLaneUsable
bool m_lastPointRightLaneUsable
Definition: MapDataLayer.hpp:52
galaxis::utils
Definition: clock.hpp:5
galaxis::lina::Vector2i
Eigen::Vector2i Vector2i
Definition: linatypes.hpp:13
MapDataLayer::init
void init()
Definition: MapDataLayer.cpp:28
galaxis::utils::log
void log(const Args &... args)
Definition: logger.hpp:33
MapDataLayer::m_threadPool
boost::asio::thread_pool m_threadPool
Definition: MapDataLayer.hpp:62