00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "field_drawer.h"
00023
00024 #include <core/exceptions/software.h>
00025 #include <fvutils/base/roi.h>
00026 #include <fvutils/draw/drawer.h>
00027 #include <fvutils/ipc/shm_image.h>
00028
00029 #include <cmath>
00030 #include <cstring>
00031 #include <stdio.h>
00032
00033 using namespace fawkes;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 FieldDrawer::FieldDrawer(const FieldLines &lines) :
00056 __lines(lines)
00057 {
00058 __points = NULL;
00059 __points_est = NULL;
00060
00061 clear_own_pos();
00062
00063 set_color_background(YUV_t::black());
00064 set_color_field(YUV_t::green());
00065 set_color_lines(YUV_t::white());
00066
00067 set_color_own_pos(YUV_t::cyan());
00068 set_color_line_points(YUV_t::cyan());
00069
00070 set_color_own_pos_est(YUV_t::yellow());
00071 set_color_line_points_est(YUV_t::yellow());
00072 }
00073
00074
00075
00076
00077 FieldDrawer::~FieldDrawer()
00078 {
00079 }
00080
00081
00082
00083
00084
00085
00086 void
00087 FieldDrawer::set_head_yaw(float head_yaw)
00088 {
00089 __head_yaw = head_yaw;
00090 }
00091
00092
00093
00094
00095
00096
00097 void
00098 FieldDrawer::set_own_pos(field_pos_t own_position)
00099 {
00100 __own_position = own_position;
00101 }
00102
00103
00104
00105
00106
00107
00108 void
00109 FieldDrawer::set_own_pos_est(field_pos_t own_position_estimate)
00110 {
00111 __own_pos_est = own_position_estimate;
00112 }
00113
00114
00115
00116
00117
00118 void
00119 FieldDrawer::clear_own_pos()
00120 {
00121 __own_position.ori = 12345;
00122 __own_pos_est.ori = 12345;
00123 __head_yaw = 12345;
00124 __points = NULL;
00125 __points_est = NULL;
00126
00127 _img_buffer = NULL;
00128 _img_width = 0;
00129 _img_height = 0;
00130 }
00131
00132
00133
00134
00135
00136
00137 void
00138 FieldDrawer::set_line_points(const fld_line_points_t *points)
00139 {
00140 __points = points;
00141 }
00142
00143
00144
00145
00146
00147
00148 void
00149 FieldDrawer::set_line_points_est(const fld_line_points_t *points_est)
00150 {
00151 __points_est = points_est;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 float
00164 FieldDrawer::get_scale(unsigned int img_width, unsigned int img_height, bool draw_landscape) const
00165 {
00166 float f_width = (draw_landscape ? __lines.get_field_length() : __lines.get_field_width());
00167 float f_height = (draw_landscape ? __lines.get_field_width() : __lines.get_field_length());
00168 return std::min(img_width / f_width, img_height / f_height);
00169 }
00170
00171
00172
00173
00174
00175 void
00176 FieldDrawer::set_color_background(YUV_t color)
00177 {
00178 __c_background = color;
00179 }
00180
00181
00182
00183
00184
00185 void
00186 FieldDrawer::set_color_field(YUV_t color)
00187 {
00188 __c_field = color;
00189 }
00190
00191
00192
00193
00194
00195 void
00196 FieldDrawer::set_color_lines(YUV_t color)
00197 {
00198 __c_lines = color;
00199 }
00200
00201
00202
00203
00204
00205 void
00206 FieldDrawer::set_color_line_points(YUV_t color)
00207 {
00208 __c_line_points = color;
00209 }
00210
00211
00212
00213
00214
00215 void
00216 FieldDrawer::set_color_line_points_est(YUV_t color)
00217 {
00218 __c_line_points_est = color;
00219 }
00220
00221
00222
00223
00224
00225 void
00226 FieldDrawer::set_color_own_pos(YUV_t color)
00227 {
00228 __c_own_pos = color;
00229 }
00230
00231
00232
00233
00234
00235 void
00236 FieldDrawer::set_color_own_pos_est(YUV_t color)
00237 {
00238 __c_own_pos_est = color;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 void
00254 FieldDrawer::draw_field(unsigned char *yuv422_planar, unsigned int img_width, unsigned int img_height,
00255 bool draw_background, bool draw_landscape)
00256 {
00257 _img_buffer = yuv422_planar;
00258 _img_width = img_width;
00259 _img_height = img_height;
00260
00261 float f_width = (draw_landscape ? __lines.get_field_length() : __lines.get_field_width());
00262 float f_height = (draw_landscape ? __lines.get_field_width() : __lines.get_field_length());
00263 float scale = std::min(_img_width / f_width, _img_height / f_height);
00264
00265 if (draw_background) {
00266 unsigned int draw_width = static_cast<unsigned int>(f_width * scale);
00267 unsigned int draw_height = static_cast<unsigned int>(f_height * scale);
00268 unsigned int u_offset = _img_width * _img_height;
00269 unsigned int v_offset = u_offset + u_offset / 2;
00270
00271 if (_img_width == draw_width) {
00272 unsigned int offset = (_img_height - draw_height) / 2;
00273 memset(_img_buffer, __c_background.Y, offset * _img_width);
00274 memset(_img_buffer + offset * _img_width, __c_field.Y, draw_height * _img_width);
00275 memset(_img_buffer + (offset + draw_height) * _img_width, __c_background.Y, offset * _img_width);
00276
00277 offset /= 2;
00278 draw_height /= 2;
00279
00280 memset(_img_buffer + u_offset, __c_background.U, offset * _img_width);
00281 memset(_img_buffer + u_offset + offset * _img_width, __c_field.U, draw_height * _img_width);
00282 memset(_img_buffer + u_offset + (offset + draw_height) * _img_width, __c_background.U, offset * _img_width);
00283
00284 memset(_img_buffer + v_offset, __c_background.V, offset * _img_width);
00285 memset(_img_buffer + v_offset + offset * _img_width, __c_field.V, draw_height * _img_width);
00286 memset(_img_buffer + v_offset + (offset + draw_height) * _img_width, __c_background.V, offset * _img_width);
00287 } else {
00288
00289 unsigned int sx = (_img_width - draw_width) / 2;
00290 unsigned int sy = (_img_height - draw_height) / 2;
00291
00292 ROI f_roi(sx,sy, draw_width,draw_height, _img_width,_img_height);
00293 for (unsigned int x = 0; x < _img_width; ++x) {
00294 for (unsigned int y = 0; y < _img_height; ++y) {
00295 if (f_roi.contains(x, y)) {
00296 _img_buffer[y * _img_width + x] = __c_field.Y;
00297 _img_buffer[(y * _img_width + x) / 2 + u_offset] = __c_field.U;
00298 _img_buffer[(y * _img_width + x) / 2 + v_offset] = __c_field.V;
00299 } else {
00300 _img_buffer[y * _img_width + x] = __c_background.Y;
00301 _img_buffer[(y * _img_width + x) / 2 + u_offset] = __c_background.U;
00302 _img_buffer[(y * _img_width + x) / 2 + v_offset] = __c_background.V;
00303 }
00304 }
00305 }
00306 }
00307 } else {
00308 unsigned int size = _img_width * _img_height;
00309 memset(_img_buffer, 0, size);
00310 memset(_img_buffer + size, 128, size);
00311 }
00312
00313
00314 draw_lines(__c_lines, draw_landscape, scale);
00315
00316 cart_coord_2d_t f_offs = __lines.get_field_offsets();
00317 unsigned int center_x = std::max(0, static_cast<int>(_img_width / 2) + static_cast<int>(f_offs.x * scale));
00318 unsigned int center_y = std::max(0, static_cast<int>(_img_height / 2) + static_cast<int>(f_offs.y * scale));
00319
00320 if (__own_pos_est.ori != 12345) {
00321 Drawer d;
00322 d.set_buffer(_img_buffer, _img_width, _img_height);
00323 d.set_color(__c_own_pos_est);
00324 unsigned int r = _img_width / 40;
00325 int x = static_cast<int>(__own_pos_est.x * scale);
00326 int y = static_cast<int>(__own_pos_est.y * scale);
00327 int dx = static_cast<int>(r * cosf(__own_pos_est.ori));
00328 int dy = static_cast<int>(r * sinf(__own_pos_est.ori));
00329
00330 if (draw_landscape) {
00331 x += center_x;
00332 y = center_y - y;
00333 d.draw_circle(x, y, r);
00334 d.draw_line(x, y, x + dx, y - dy);
00335 } else {
00336 x += center_y;
00337 y = center_x - y;
00338 d.draw_circle(y, x, r);
00339 d.draw_line(y, x, y + dy, x - dx);
00340 }
00341
00342 if(__head_yaw != 12345) {
00343 int hx = static_cast<int>(r * cosf(__own_pos_est.ori + __head_yaw));
00344 int hy = static_cast<int>(r * sinf(__own_pos_est.ori + __head_yaw));
00345 int hdx = static_cast<int>((r + 4) * cosf(__own_pos_est.ori + __head_yaw));
00346 int hdy = static_cast<int>((r + 4) * sinf(__own_pos_est.ori + __head_yaw));
00347
00348 if (draw_landscape) d.draw_line(x + hx, y - hy, x + hdx, y - hdy);
00349 else d.draw_line(y + hy, x - hx, y + hdy, x - hdx);
00350 }
00351 }
00352
00353 if (__own_position.ori != 12345) {
00354 Drawer d;
00355 d.set_buffer(_img_buffer, _img_width, _img_height);
00356 d.set_color(__c_own_pos);
00357 unsigned int r = _img_width / 40;
00358 int x = static_cast<int>(__own_position.x * scale);
00359 int y = static_cast<int>(__own_position.y * scale);
00360 int dx = static_cast<int>(r * cosf(__own_position.ori));
00361 int dy = static_cast<int>(r * sinf(__own_position.ori));
00362
00363 if (draw_landscape) {
00364 x += center_x;
00365 y = center_y - y;
00366 d.draw_circle(x, y, r);
00367 d.draw_line(x, y, x + dx, y - dy);
00368 } else {
00369 x += center_y;
00370 y = center_x - y;
00371 d.draw_circle(y, x, r);
00372 d.draw_line(y, x, y + dy, x - dx);
00373 }
00374
00375 if(__head_yaw != 12345) {
00376 int hx = static_cast<int>(r * cosf(__own_position.ori + __head_yaw));
00377 int hy = static_cast<int>(r * sinf(__own_position.ori + __head_yaw));
00378 int hdx = static_cast<int>((r + 4) * cosf(__own_position.ori + __head_yaw));
00379 int hdy = static_cast<int>((r + 4) * sinf(__own_position.ori + __head_yaw));
00380
00381 if (draw_landscape) d.draw_line(x + hx, y - hy, x + hdx, y - hdy);
00382 else d.draw_line(y + hy, x - hx, y + hdy, x - hdx);
00383 }
00384 }
00385
00386 draw_line_points(draw_landscape, scale);
00387 clear_own_pos();
00388 }
00389
00390
00391
00392
00393
00394
00395 void
00396 FieldDrawer::draw_line_points(bool draw_landscape, float scale) const
00397 {
00398 if (!scale) {
00399 if (draw_landscape) scale = std::min(_img_width / __lines.get_field_length(), _img_height / __lines.get_field_width());
00400 else scale = std::min(_img_width / __lines.get_field_width(), _img_height / __lines.get_field_length());
00401 }
00402
00403 cart_coord_2d_t f_offs = __lines.get_field_offsets();
00404 unsigned int center_x = std::max(0, static_cast<int>(_img_width / 2) + static_cast<int>(f_offs.x * scale));
00405 unsigned int center_y = std::max(0, static_cast<int>(_img_height / 2) + static_cast<int>(f_offs.y * scale));
00406
00407 Drawer d;
00408 d.set_buffer(_img_buffer, _img_width, _img_height);
00409
00410 if (__points_est) {
00411 d.set_color(__c_line_points_est);
00412 for (fld_line_points_t::const_iterator it = __points_est->begin(); it != __points_est->end(); ++it) {
00413 unsigned int y = static_cast<unsigned int>(center_y - (draw_landscape ? it->y : it->x) * scale);
00414 unsigned int x =static_cast<unsigned int>((draw_landscape ? it->x : it->y) * scale + center_x);
00415
00416 d.draw_cross(x, y, 4);
00417 }
00418 }
00419
00420 if (__points) {
00421 d.set_color(__c_line_points);
00422 for (fld_line_points_t::const_iterator it = __points->begin(); it != __points->end(); ++it) {
00423 unsigned int y = static_cast<unsigned int>(center_y - (draw_landscape ? it->y : it->x) * scale);
00424 unsigned int x = static_cast<unsigned int>((draw_landscape ? it->x : it->y) * scale + center_x);
00425
00426 d.draw_cross(x, y, 4);
00427 }
00428 }
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 void
00440 FieldDrawer::draw_lines(YUV_t color, bool draw_landscape, float scale) const
00441 {
00442 if (!scale) {
00443 if (draw_landscape) scale = std::min(_img_width / __lines.get_field_length(), _img_height / __lines.get_field_width());
00444 else scale = std::min(_img_width / __lines.get_field_width(), _img_height / __lines.get_field_length());
00445 }
00446
00447 cart_coord_2d_t f_offs = __lines.get_field_offsets();
00448 int f_off_x = static_cast<int>(f_offs.x * scale);
00449 int f_off_y = static_cast<int>(f_offs.y * scale);
00450
00451 unsigned int off_x = std::max(0, static_cast<int>(_img_width / 2) + f_off_x);
00452 unsigned int off_y = std::max(0, static_cast<int>(_img_height / 2) + f_off_y);
00453
00454 Drawer d;
00455 d.set_buffer(_img_buffer, _img_width, _img_height);
00456 d.set_color(color);
00457
00458 for (FieldLines::const_iterator it = __lines.begin(); it != __lines.end(); ++it) {
00459 unsigned int sx = static_cast<unsigned int>((draw_landscape ? (*it).start.x : (*it).start.y) * scale);
00460 unsigned int sy = static_cast<unsigned int>((draw_landscape ? (*it).start.y : (*it).start.x) * scale);
00461 unsigned int ex = static_cast<unsigned int>((draw_landscape ? (*it).end.x : (*it).end.y) * scale);
00462 unsigned int ey = static_cast<unsigned int>((draw_landscape ? (*it).end.y : (*it).end.x) * scale);
00463
00464 d.draw_line(off_x + sx, off_y + sy, off_x + ex, off_y + ey);
00465 }
00466
00467 for (field_circles_t::const_iterator it = __lines.get_circles().begin(); it != __lines.get_circles().end(); ++it) {
00468 unsigned int cx = static_cast<unsigned int>((draw_landscape ? it->center.x : it->center.y) * scale);
00469 unsigned int cy = static_cast<unsigned int>((draw_landscape ? it->center.y : it->center.x) * scale);
00470 unsigned int r = static_cast<unsigned int>(it->radius * scale);
00471
00472 d.draw_circle(off_x + cx, off_y + cy, r);
00473 }
00474 }
00475
00476