Roomba App  1.0
glWidget.cpp
Go to the documentation of this file.
1 
15 #include <GL/gl.h>
16 #include <GL/glu.h>
17 #include <GL/glut.h>
18 #include <SOIL/SOIL.h>
19 #include <cmath>
20 
21 #include "glWidget.hh"
22 
23 static GLuint textureWheel;
24 static GLuint textureRobot;
25 static float angle;
26 
27 GLWidget::GLWidget(QWidget* parent) : QGLViewer(parent)
28 {
29  _wheelTexturePath = "textures/wheel.png";
30  _robotTexturePath = "textures/robot.png";
31 }
32 
33 void GLWidget::obstacleDataReady(const std::map<float, int>& obstacleData)
34 {
35  _obstacleCoordinates.clear();
36  _obstacleColors.clear();
37 
38  std::vector<float> distances;
39 
40  for(const auto& [angle, distance] : obstacleData)
41  {
42  float radianAngle = ((angle + 1) * PI) / 180.0;
43 
44  float x = distance * _dimensions.scale * cos(radianAngle);
45  float y = distance * _dimensions.scale * sin(radianAngle);
46  float z = _dimensions.lidarHeight;
47  _obstacleCoordinates.push_back({x, y, z});
48  distances.push_back(distance);
49  }
50 
51  float min = *std::min_element(std::begin(distances), std::end(distances));
52  float max = *std::max_element(std::begin(distances), std::end(distances));
53 
54  for(const auto& distance : distances)
55  {
56  float color = (distance - min) / (max - min) * 255.0;
57  _obstacleColors.push_back(color);
58  }
59 
60  updateGL();
61 }
62 
63 void GLWidget::rightWheelDirection(const int& direction)
64 {
65  _rightWheelDirection = direction;
66 }
67 
68 void GLWidget::leftWheelDirection(const int& direction)
69 {
70  _leftWheelDirection = direction;
71 }
72 
74 {
75  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
76  glEnable(GL_TEXTURE_2D);
77 
78  // Background
79  glClearColor(0.5, 0.5, 0.5, 1);
80 
81  drawRobot();
82 
83  for(unsigned long i = 0; i < _obstacleCoordinates.size(); i++)
84  {
86  _obstacleColors[i]);
87  }
88 
89  glFlush();
90 }
91 
93 {
94  restoreStateFromFile();
95 
96  GLfloat lightPosition[] = {1.0, 1.0, 1.0, 0.0};
97  glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
98 
99  glEnable(GL_LIGHTING);
100  glEnable(GL_LIGHT0);
101  glEnable(GL_DEPTH_TEST);
102 
103  glEnable(GL_TEXTURE_2D);
104  loadTexture(&textureWheel, _wheelTexturePath.toStdString());
105  loadTexture(&textureRobot, _robotTexturePath.toStdString());
106  // help();
107 }
108 
109 QString GLWidget::helpString() const
110 {
111  QString text("<h2>S i m p l e V i e w e r</h2>");
112  text += "Use the mouse to move the camera around the object. ";
113  text += "You can respectively revolve around, zoom and translate with the three mouse buttons. ";
114  text += "Left and middle buttons pressed together rotate around the camera view direction axis<br><br>";
115  text += "Pressing <b>Alt</b> and one of the function keys (<b>F1</b>..<b>F12</b>) defines a camera keyFrame. ";
116  text += "Simply press the function key again to restore it. Several keyFrames define a ";
117  text += "camera path. Paths are saved when you quit the application and restored at next start.<br><br>";
118  text += "Press <b>F</b> to display the frame rate, <b>A</b> for the world axis, ";
119  text += "<b>Alt+Return</b> for full screen mode and <b>Control+S</b> to save a snapshot. ";
120  text += "See the <b>Keyboard</b> tab in this window for a complete shortcut list.<br><br>";
121  text += "Double clicks automates single click actions: A left button double click aligns the closer axis with the "
122  "camera (if close enough). ";
123  text +=
124  "A middle button double click fits the zoom of the camera and the right button re-centers the scene.<br><br>";
125  text += "A left button double click while holding right button pressed defines the camera <i>Revolve Around "
126  "Point</i>. ";
127  text += "See the <b>Mouse</b> tab and the documentation web pages for details.<br><br>";
128  text += "Press <b>Escape</b> to exit the viewer.";
129  return text;
130 }
131 
132 void GLWidget::loadTexture(GLuint* texture, const std::string& path)
133 {
134  glEnable(GL_TEXTURE_2D);
135  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
136  glGenTextures(1, texture);
137  glBindTexture(GL_TEXTURE_2D, *texture);
138 
139  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
140 
141  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
142  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
143  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
144  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
145 
146  int width, height;
147  unsigned char* image = SOIL_load_image(path.c_str(), &width, &height, 0, SOIL_LOAD_RGB);
148 
149  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
150 }
151 
153 {
154  _drawCylinder(_dimensions.robotRadius, _dimensions.robotHeight, 10, 10, 10, textureRobot);
155 
156  glPushMatrix();
157  glPushMatrix();
158 
160  glRotatef(90, 0, 1, 0);
161  glRotatef(_rightWheelDirection * angle, 0, 0, 1);
163 
164  glPopMatrix();
165 
167  glRotatef(-90, 0, 1, 0);
168  glRotatef(_leftWheelDirection * angle, 0, 0, 1);
170 
171  angle += 10.0;
172  angle = std::fmod(angle, 360.0);
173 
174  glPopMatrix();
175 }
176 
177 void GLWidget::drawOneObstacle(GLfloat x, GLfloat y, GLfloat z, GLfloat color)
178 {
179  glPushMatrix();
180  glTranslatef(x, y, z);
181 
182  _drawCube(_dimensions.obstacleSize, 0, color, 0);
183  glPopMatrix();
184 }
185 
186 void GLWidget::_drawCube(GLfloat size, GLubyte R, GLubyte G, GLubyte B)
187 {
188  glPushMatrix();
189 
190  glColor3ub(R, G, B);
191  glBegin(GL_POLYGON);
192  glVertex3f(size, -size, size);
193  glVertex3f(size, size, size);
194  glVertex3f(-size, size, size);
195  glVertex3f(-size, -size, size);
196  glEnd();
197 
198  glColor3ub(R, G, B);
199  glBegin(GL_POLYGON);
200  glVertex3f(size, -size, -size);
201  glVertex3f(size, size, -size);
202  glVertex3f(size, size, size);
203  glVertex3f(size, -size, size);
204  glEnd();
205 
206  glColor3ub(R, G, B);
207  glBegin(GL_POLYGON);
208  glVertex3f(-size, -size, size);
209  glVertex3f(-size, size, size);
210  glVertex3f(-size, size, -size);
211  glVertex3f(-size, -size, -size);
212  glEnd();
213 
214  glColor3ub(R, G, B);
215  glBegin(GL_POLYGON);
216  glVertex3f(size, size, size);
217  glVertex3f(size, size, -size);
218  glVertex3f(-size, size, -size);
219  glVertex3f(-size, size, size);
220  glEnd();
221 
222  glColor3ub(R, G, B);
223  glBegin(GL_POLYGON);
224  glVertex3f(size, -size, -size);
225  glVertex3f(size, -size, size);
226  glVertex3f(-size, -size, size);
227  glVertex3f(-size, -size, -size);
228  glEnd();
229 
230  glPopMatrix();
231 }
232 
233 void GLWidget::_drawCylinder(GLfloat radius, GLfloat height, GLubyte R, GLubyte G, GLubyte B, GLuint texture)
234 {
235  glEnable(GL_TEXTURE_2D);
236  glBindTexture(GL_TEXTURE_2D, texture);
237 
238  double i, resolution = 0.001;
239 
240  glPushMatrix();
241  glRotatef(90, 1, 0, 0);
242 
243  /* Top triangle */
244  glBegin(GL_TRIANGLE_FAN);
245  glTexCoord2f(0.5, 0.5);
246  glVertex3f(0, height, 0);
247  i = 2 * PI;
248  while(i >= 0)
249  {
250  glTexCoord2f(0.5f * cos(i) + 0.5f, 0.5f * sin(i) + 0.5f);
251  glVertex3f(radius * cos(i), height, radius * sin(i));
252  i -= resolution;
253  }
254  glTexCoord2f(0.5, 0.5);
255  glVertex3f(radius, height, 0);
256  glEnd();
257 
258  glDisable(GL_TEXTURE_2D);
259 
260  /* Bottom triangle */
261  glColor3ub(R, G, B);
262  glBegin(GL_TRIANGLE_FAN);
263  // glTexCoord2f(0.5, 0.5);
264  glVertex3f(0, 0, 0);
265  i = 0;
266  while(i <= 2 * PI)
267  {
268  // glTexCoord2f(0.5f * cos(i) + 0.5f, 0.5f * sin(i) + 0.5f);
269  glVertex3f(radius * cos(i), 0, radius * sin(i));
270  i += resolution;
271  }
272  glEnd();
273 
274  /* Middle tube */
275  glColor3ub(R, G, B);
276  glBegin(GL_QUAD_STRIP);
277  i = 0;
278  while(i <= 2 * PI)
279  {
280  // const float tc = (i / (float)(2 * PI));
281  // glTexCoord2f(tc, 0.0);
282  glVertex3f(radius * cos(i), 0, radius * sin(i));
283  // glTexCoord2f(tc, 1.0);
284  glVertex3f(radius * cos(i), height, radius * sin(i));
285  i += resolution;
286  }
287  // glTexCoord2f(0.0, 0.0);
288  glVertex3f(radius, 0, 0);
289  // glTexCoord2f(0.0, 1.0);
290  glVertex3f(radius, height, 0);
291  glEnd();
292 
293  glPopMatrix();
294 }
void loadTexture(GLuint *texture, const std::string &path)
Load a texture object.
Definition: glWidget.cpp:132
std::vector< float > _obstacleColors
All obstacles colors.
Definition: glWidget.hh:122
void obstacleDataReady(const std::map< float, int > &lidarData)
A slot to get a lidar data when the parser sent a signal that this data is ready.
Definition: glWidget.cpp:33
struct GLWidget::Dimensions _dimensions
void drawRobot()
Draw the robot shape.
Definition: glWidget.cpp:152
void drawOneObstacle(GLfloat x, GLfloat y, GLfloat z, GLfloat color)
Draw the one obstacle on (x, y, z) coordinates.
Definition: glWidget.cpp:177
GLWidget(QWidget *parent)
Construct a new GLWidget object.
Definition: glWidget.cpp:27
QString _robotTexturePath
The path to the robot texture file.
Definition: glWidget.hh:118
void rightWheelDirection(const int &direction)
A slot to get a right wheel spining direction.
Definition: glWidget.cpp:63
std::vector< std::vector< float > > _obstacleCoordinates
All obstacles coordinates in 3D space.
Definition: glWidget.hh:121
int _leftWheelDirection
The left robot wheel spining direction.
Definition: glWidget.hh:120
void _drawCube(GLfloat size, GLubyte R, GLubyte G, GLubyte B)
Draw a cube shape.
Definition: glWidget.cpp:186
virtual void init() override
Initialize the openGL widget.
Definition: glWidget.cpp:92
int _rightWheelDirection
The right robot wheel spining direction.
Definition: glWidget.hh:119
virtual void draw() override
Draw a content in the openGL widget.
Definition: glWidget.cpp:73
virtual QString helpString() const override
Construct a help string for the openGL widget.
Definition: glWidget.cpp:109
void leftWheelDirection(const int &direction)
A slot to get the left wheel spining direction.
Definition: glWidget.cpp:68
QString _wheelTexturePath
The path to the wheel texture file.
Definition: glWidget.hh:117
void _drawCylinder(GLfloat radius, GLfloat height, GLubyte R, GLubyte G, GLubyte B, GLuint texture)
Draw the cylinder shape with the texture on the top.
Definition: glWidget.cpp:233
GLWidget class declaration.
#define PI
Definition: glWidget.hh:20
const float robotWheelRadius
The wheel radius.
Definition: glWidget.hh:137
const float scale
The general scale.
Definition: glWidget.hh:134
const float obstacleSize
A size of the cube drawn as obstacle.
Definition: glWidget.hh:140
const float robotHeight
The obot body height.
Definition: glWidget.hh:135
const float robotRadius
The robot body radius.
Definition: glWidget.hh:136
const float lidarHeight
The laser sensor height.
Definition: glWidget.hh:139
const float robotWheelThickness
The wheel thickness.
Definition: glWidget.hh:138