se2ez
cspace.h
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #ifndef SE2EZ_CORE_CSPACE_
4 #define SE2EZ_CORE_CSPACE_
5 
6 #include <ompl/util/PPM.h>
7 
8 #include <queue>
9 #include <thread>
10 #include <mutex>
11 #include <condition_variable>
12 
14 #include <se2ez/core/robot.h>
15 
16 namespace se2ez
17 {
18  /** \cond IGNORE */
19  SE2EZ_CLASS_FORWARD(State)
20  /** \endcond */
21 
22  /** \cond IGNORE */
23  SE2EZ_CLASS_FORWARD(CSpaceGrid)
24  /** \endcond */
25 
26  /** \class se2ez::CSpaceGridPtr
27  \brief A shared pointer wrapper for se2ez::CSpaceGrid. */
28 
29  /** \class se2ez::CSpaceGridConstPtr
30  \brief A const shared pointer wrapper for se2ez::CSpaceGrid. */
31 
32  /** \brief Helper class to compute and draw C-Space images from arbitrary robots.
33  */
34  class CSpaceGrid
35  {
36  public:
37  /** \brief Grid coordinates.
38  */
39  struct GridCoords
40  {
41  unsigned int x; ///< x coordinate.
42  unsigned int y; ///< y coordinate.
43  };
44 
45  /** \brief Line on the grid.
46  */
47  struct GridLine
48  {
49  GridCoords a; ///< Endpoint a.
50  GridCoords b; ///< Endpoint b.
51  };
52 
53  /** \brief Coordinates for the robot.
54  */
55  struct RobotCoords
56  {
57  double x; ///< x coordinate
58  double y; ///< y coordinate
59  };
60 
61  /** \brief Drawing mode for the grid.
62  */
63  enum Mode
64  {
65  COLLISION, ///< Draw collisions as black pixels.
66  COLOR, ///< Color obstacles by geometry color.
67  DISTANCE, ///< Use `viridis` color palette for signed distance.
68  DISTANCE_COLOR, ///< Signed distance, but penetrations are colored by geometry.
69  };
70 
71  /** \brief Function to callback for grid computation. Gives a pixel to color, the state, and whether
72  * the state is in collision.
73  */
75 
76  /** \brief Constructor.
77  * \param[in] robot Robot to compute grid for.
78  * \param[in] jointA index of configuration to vary.
79  * \param[in] jointB other index of configuration to vary.
80  * \param[in] width Width of image to compute.
81  * \param[in] height Height of image to compute.
82  * \param[in] mode What mode to use for rendering.
83  */
84  CSpaceGrid(const RobotPtr &robot, unsigned int jointA, unsigned int jointB, //
85  unsigned int width = 500, unsigned int height = 500, Mode mode = COLLISION);
86 
87  /** \brief Constructor.
88  * \param[in] robot Robot to compute grid for.
89  * \param[in] jointA 1-DoF joint to vary.
90  * \param[in] jointB other 1-DoF joint to vary.
91  * \param[in] width Width of image to compute.
92  * \param[in] height Height of image to compute.
93  * \param[in] mode What mode to use for rendering.
94  */
95  CSpaceGrid(const RobotPtr &robot, const std::string &jointA, const std::string &jointB,
96  unsigned int width = 500, unsigned int height = 500, Mode mode = COLLISION);
97 
98  /** \brief Destructor.
99  */
100  ~CSpaceGrid();
101 
102  /** \brief Compute a PPM image of the configuration space of two joints, \e jointA and \e jointB.
103  * \param[in] block Wait for computation to finish. If false, returns immediately.
104  * \param[in] base For robots with more than 2 DoF, set other DoF to this state.
105  * \param[in] callback Extra callback function to draw extra information.
106  */
107  void compute(bool block = true, const StatePtr &base = nullptr, const GridCallback &callback = {});
108 
109  /** \brief Wait for all grid computation to complete.
110  */
111  void waitToComplete();
112 
113  /** \brief Checks if any computation is happening.
114  */
115  bool isComputing() const;
116 
117  /** \brief Cancels any remaining computation.
118  */
119  void cancel();
120 
121  /** \brief Get the pixel coordinate for a configuration.
122  * \param[in] state State to use for configuration values.
123  * \return Reference to pixel to set.
124  */
125  ompl::PPM::Color &getPixel(const StatePtr &state);
126 
127  /** \brief Get the pixel coordinate for a configuration of \e i for jointA and \e j for jointB.
128  * \param[in] i Value for jointA.
129  * \param[in] j Value for jointB.
130  * \return Reference to pixel to set.
131  */
132  ompl::PPM::Color &getPixel(double i, double j);
133 
134  /** \brief Get the pixel coordinate for a configuration.
135  * \param[in] state State to use for configuration values.
136  * \return Pixel coordinates.
137  */
138  GridCoords getCoords(const StatePtr &state);
139 
140  /** \brief Get the pixel coordinate for a configuration.
141  * \param[in] i Configuration for first joint.
142  * \param[in] j Configuration for second joint.
143  * \return Pixel coordinates.
144  */
145  GridCoords getCoords(double i, double j);
146 
147  /** \brief Get the associated robot configuration from image coordinates.
148  * \param[in] i X-coordinate
149  * \param[in] j Y-coordinate
150  * \return Robot configuration.
151  */
152  RobotCoords getCoords(unsigned int i, unsigned int j);
153 
154  /** \brief Get the line segments between two points on the grid. Can have two due to wrapping.
155  * \param[in] a Endpoint a
156  * \param[in] b Endpoint b
157  * \return Grid lines.
158  */
159  std::vector<GridLine> getLines(const StatePtr &a, const StatePtr &b);
160 
161  /** \brief Get the current computed PPM image.
162  * \return A PPM image with black meaning the robot is in collision, white if it is not in
163  * collision.
164  */
165  std::shared_ptr<ompl::PPM> getImage() const;
166 
167  /** \brief Returns the distance along the dimensions of the robot not captured by the current C-Space
168  * slice.
169  * \param[in] state State to measure distance to.
170  * \return The distance of the state to the slice.
171  */
172  double distanceToSlice(const StatePtr &state);
173 
174  /** \brief Returns a value in [0, 1] of the progress of the current computation.
175  * \return Current progress value.
176  */
177  double progress() const;
178 
179  /** \brief Return width of grid.
180  * \return The width of the grid.
181  */
182  unsigned int getWidth() const;
183 
184  /** \brief Return height of grid.
185  * \return The height of the grid.
186  */
187  unsigned int getHeight() const;
188 
189  private:
190  /** \brief Initialize all internal constructs.
191  */
192  void initialize();
193 
194  /** \brief Emplaces all images chunks into work queue.
195  */
196  void emplaceChunks();
197 
198  /** \brief Gets the average color of a frame.
199  * \param[in] frame Frame to get color of.
200  * \return The average color of the frame.
201  */
202  Eigen::Vector4d getFrameColor(const std::string &frame) const;
203 
204  const RobotPtr robot_; ///< Robot to use.
205  const unsigned int xChunk_{25}; ///< Size of X chunk for threading.
206  const unsigned int yChunk_{25}; ///< Size of Y chunk for threading.
207  const double minDepth_{-1.}; ///< Minimum value for signed distance color map.
208  const double maxDepth_{1.}; ///< Maximum value for signed distance color map.
209 
210  static const unsigned int cores_; ///< Number of cores on the machine
211  const unsigned int indexA_; ///< Joint index for X-axis
212  const unsigned int indexB_; ///< Joint index for Y-axis
213  const Eigen::Vector2d limitA_; ///< Joint limits for first joint (1-DoF)
214  const Eigen::Vector2d limitB_; ///< Joint limits for second joint (1-DoF)
215  const bool contA_; ///< Is joint A continuous?
216  const bool contB_; ///< Is joint B continuous?
217 
218  const unsigned int width_; ///< Width of image.
219  const unsigned int height_; ///< Height of image.
220  const Mode mode_; ///< Render mode.
221  std::shared_ptr<ompl::PPM> image_{nullptr}; ///< Image itself.
222 
223  /** \brief Container class for image chunk information to worker threads.
224  */
225  struct Chunk
226  {
227  /** \brief Default constructor.
228  */
229  Chunk() = default;
230 
231  /** \brief Constructor.
232  * \param[in] x Starting x coordinate.
233  * \param[in] y Starting y coordinate.
234  * \param[in] w Width of chunk.
235  * \param[in] h Height of chunk.
236  */
237  Chunk(unsigned int x, unsigned int y, unsigned int w, unsigned int h) : x(x), y(y), w(w), h(h)
238  {
239  }
240 
241  unsigned int x; ///< Starting x coordinate of chunk.
242  unsigned int y; ///< Starting y coordinate of chunk.
243  unsigned int w; ///< Width of chunk.
244  unsigned int h; ///< Height of chunk.
245  };
246 
247  unsigned int maxChunks_{0}; ///< Maximum number of chunks in queue.
248  StatePtr state_{nullptr}; ///< State provided through compute().
249  StatePtr temp_{nullptr}; ///< Temporary state.
250  GridCallback callback_{}; ///< Callback function to use for extra drawing.
251 
252  bool done_{false}; ///< Notify threads object is to be destroyed.
253  std::mutex lock_; ///< Mutex.
254  std::mutex statelock_; ///< Mutex for state.
255  std::condition_variable work_; ///< Condition variable that there is work to do.
256  std::condition_variable complete_; ///< Condition variable to notify when complete.
257  std::queue<Chunk> chunks_; ///< Queue of chunks.
258 
259  std::vector<bool> newState_; ///< Has each thread updated to new base state for computation?
260  std::vector<bool> working_; ///< Which threads are currently working?
262  };
263 } // namespace se2ez
264 
265 #endif
unsigned int y
y coordinate.
Definition: cspace.h:42
Container class for image chunk information to worker threads.
Definition: cspace.h:225
const unsigned int indexB_
Joint index for Y-axis.
Definition: cspace.h:212
A shared pointer wrapper for se2ez::State.
Coordinates for the robot.
Definition: cspace.h:55
GridCoords b
Endpoint b.
Definition: cspace.h:50
GridCoords a
Endpoint a.
Definition: cspace.h:49
unsigned int x
x coordinate.
Definition: cspace.h:41
Chunk(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Constructor.
Definition: cspace.h:237
std::vector< bool > newState_
Has each thread updated to new base state for computation?
Definition: cspace.h:259
Mode
Drawing mode for the grid.
Definition: cspace.h:63
std::mutex lock_
Mutex.
Definition: cspace.h:253
const unsigned int width_
Width of image.
Definition: cspace.h:218
std::vector< bool > working_
Which threads are currently working?
Definition: cspace.h:260
std::condition_variable work_
Condition variable that there is work to do.
Definition: cspace.h:255
std::mutex statelock_
Mutex for state.
Definition: cspace.h:254
const RobotPtr robot_
Robot to use.
Definition: cspace.h:204
std::condition_variable complete_
Condition variable to notify when complete.
Definition: cspace.h:256
static const unsigned int cores_
Number of cores on the machine.
Definition: cspace.h:210
const unsigned int height_
Height of image.
Definition: cspace.h:219
std::queue< Chunk > chunks_
Queue of chunks.
Definition: cspace.h:257
unsigned int y
Starting y coordinate of chunk.
Definition: cspace.h:242
Use viridis color palette for signed distance.
Definition: cspace.h:67
Draw collisions as black pixels.
Definition: cspace.h:65
A shared pointer wrapper for se2ez::Robot.
const Eigen::Vector2d limitB_
Joint limits for second joint (1-DoF)
Definition: cspace.h:214
const Mode mode_
Render mode.
Definition: cspace.h:220
unsigned int w
Width of chunk.
Definition: cspace.h:243
Signed distance, but penetrations are colored by geometry.
Definition: cspace.h:68
Color obstacles by geometry color.
Definition: cspace.h:66
const bool contB_
Is joint B continuous?
Definition: cspace.h:216
double y
y coordinate
Definition: cspace.h:58
Main namespace.
Definition: collision.h:11
Grid coordinates.
Definition: cspace.h:39
double x
x coordinate
Definition: cspace.h:57
const unsigned int indexA_
Joint index for X-axis.
Definition: cspace.h:211
std::vector< std::thread * > threads_
Threads.
Definition: cspace.h:261
unsigned int x
Starting x coordinate of chunk.
Definition: cspace.h:241
unsigned int h
Height of chunk.
Definition: cspace.h:244
const Eigen::Vector2d limitA_
Joint limits for first joint (1-DoF)
Definition: cspace.h:213
Line on the grid.
Definition: cspace.h:47
#define SE2EZ_CLASS_FORWARD(C)
Definition: class_forward.h:9
const bool contA_
Is joint A continuous?
Definition: cspace.h:215
Helper class to compute and draw C-Space images from arbitrary robots.
Definition: cspace.h:34