00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <mapviz_plugins/disparity_plugin.h>
00031
00032
00033 #include <cstdio>
00034 #include <algorithm>
00035 #include <vector>
00036
00037
00038 #include <QDialog>
00039 #include <QGLWidget>
00040
00041
00042 #include <ros/master.h>
00043 #include <sensor_msgs/image_encodings.h>
00044 #include <opencv2/imgproc/imgproc.hpp>
00045
00046 #include <cv_bridge/cv_bridge.h>
00047
00048 #include <mapviz/select_topic_dialog.h>
00049
00050
00051 #include <pluginlib/class_list_macros.h>
00052
00053 PLUGINLIB_DECLARE_CLASS(
00054 mapviz_plugins,
00055 disparity,
00056 mapviz_plugins::DisparityPlugin,
00057 mapviz::MapvizPlugin)
00058
00059 namespace mapviz_plugins
00060 {
00061 DisparityPlugin::DisparityPlugin() :
00062 config_widget_(new QWidget()),
00063 anchor_(TOP_LEFT),
00064 units_(PIXELS),
00065 offset_x_(0),
00066 offset_y_(0),
00067 width_(320),
00068 height_(240),
00069 has_image_(false),
00070 last_width_(0),
00071 last_height_(0)
00072 {
00073 ui_.setupUi(config_widget_);
00074
00075
00076 QPalette p(config_widget_->palette());
00077 p.setColor(QPalette::Background, Qt::white);
00078 config_widget_->setPalette(p);
00079
00080
00081 QPalette p3(ui_.status->palette());
00082 p3.setColor(QPalette::Text, Qt::red);
00083 ui_.status->setPalette(p3);
00084
00085 QObject::connect(ui_.selecttopic, SIGNAL(clicked()), this, SLOT(SelectTopic()));
00086 QObject::connect(ui_.topic, SIGNAL(editingFinished()), this, SLOT(TopicEdited()));
00087 QObject::connect(ui_.anchor, SIGNAL(activated(QString)), this, SLOT(SetAnchor(QString)));
00088 QObject::connect(ui_.units, SIGNAL(activated(QString)), this, SLOT(SetUnits(QString)));
00089 QObject::connect(ui_.offsetx, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetX(int)));
00090 QObject::connect(ui_.offsety, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetY(int)));
00091 QObject::connect(ui_.width, SIGNAL(valueChanged(int)), this, SLOT(SetWidth(int)));
00092 QObject::connect(ui_.height, SIGNAL(valueChanged(int)), this, SLOT(SetHeight(int)));
00093 }
00094
00095 DisparityPlugin::~DisparityPlugin()
00096 {
00097 }
00098
00099 void DisparityPlugin::SetOffsetX(int offset)
00100 {
00101 offset_x_ = offset;
00102 }
00103
00104 void DisparityPlugin::SetOffsetY(int offset)
00105 {
00106 offset_y_ = offset;
00107 }
00108
00109 void DisparityPlugin::SetWidth(int width)
00110 {
00111 width_ = width;
00112 }
00113
00114 void DisparityPlugin::SetHeight(int height)
00115 {
00116 height_ = height;
00117 }
00118
00119 void DisparityPlugin::SetAnchor(QString anchor)
00120 {
00121 if (anchor == "top left")
00122 {
00123 anchor_ = TOP_LEFT;
00124 }
00125 else if (anchor == "top center")
00126 {
00127 anchor_ = TOP_CENTER;
00128 }
00129 else if (anchor == "top right")
00130 {
00131 anchor_ = TOP_RIGHT;
00132 }
00133 else if (anchor == "center left")
00134 {
00135 anchor_ = CENTER_LEFT;
00136 }
00137 else if (anchor == "center")
00138 {
00139 anchor_ = CENTER;
00140 }
00141 else if (anchor == "center right")
00142 {
00143 anchor_ = CENTER_RIGHT;
00144 }
00145 else if (anchor == "bottom left")
00146 {
00147 anchor_ = BOTTOM_LEFT;
00148 }
00149 else if (anchor == "bottom center")
00150 {
00151 anchor_ = BOTTOM_CENTER;
00152 }
00153 else if (anchor == "bottom right")
00154 {
00155 anchor_ = BOTTOM_RIGHT;
00156 }
00157 }
00158
00159 void DisparityPlugin::SetUnits(QString units)
00160 {
00161 if (units == "pixels")
00162 {
00163 units_ = PIXELS;
00164 }
00165 else if (units == "percent")
00166 {
00167 units_ = PERCENT;
00168 }
00169 }
00170
00171 void DisparityPlugin::SelectTopic()
00172 {
00173 ros::master::TopicInfo topic = mapviz::SelectTopicDialog::selectTopic(
00174 "stereo_msgs/DisparityImage");
00175
00176 if (!topic.name.empty())
00177 {
00178 ui_.topic->setText(QString::fromStdString(topic.name));
00179 TopicEdited();
00180 }
00181 }
00182
00183 void DisparityPlugin::TopicEdited()
00184 {
00185 std::string topic = ui_.topic->text().trimmed().toStdString();
00186 if(!this->Visible())
00187 {
00188 PrintWarning("Topic is Hidden");
00189 initialized_ = false;
00190 has_message_ = false;
00191 if (!topic.empty())
00192 {
00193 topic_ = topic;
00194 }
00195 disparity_sub_.shutdown();
00196 return;
00197 }
00198 if (topic != topic_)
00199 {
00200 initialized_ = false;
00201 has_message_ = false;
00202 topic_ = topic;
00203 PrintWarning("No messages received.");
00204
00205 disparity_sub_.shutdown();
00206
00207 if (!topic.empty())
00208 {
00209 disparity_sub_ = node_.subscribe(topic_, 1, &DisparityPlugin::disparityCallback, this);
00210
00211 ROS_INFO("Subscribing to %s", topic_.c_str());
00212 }
00213 }
00214 }
00215
00216 void DisparityPlugin::disparityCallback(const stereo_msgs::DisparityImageConstPtr& disparity)
00217 {
00218 if (!has_message_)
00219 {
00220 initialized_ = true;
00221 has_message_ = true;
00222 }
00223
00224 if (disparity->min_disparity == 0.0 && disparity->max_disparity == 0.0)
00225 {
00226 PrintError("Min and max disparity not set.");
00227 has_image_ = false;
00228 return;
00229 }
00230
00231 if (disparity->image.encoding != sensor_msgs::image_encodings::TYPE_32FC1)
00232 {
00233 PrintError("Invalid encoding.");
00234 has_image_ = false;
00235 return;
00236 }
00237
00238 disparity_ = *disparity;
00239
00240
00241 float min_disparity = disparity->min_disparity;
00242 float max_disparity = disparity->max_disparity;
00243 float multiplier = 255.0f / (max_disparity - min_disparity);
00244
00245 cv_bridge::CvImageConstPtr cv_disparity =
00246 cv_bridge::toCvShare(disparity->image, disparity);
00247
00248 disparity_color_.create(disparity->image.height, disparity->image.width);
00249
00250 for (int row = 0; row < disparity_color_.rows; row++)
00251 {
00252 const float* d = cv_disparity->image.ptr<float>(row);
00253 for (int col = 0; col < disparity_color_.cols; col++)
00254 {
00255 int index = static_cast<int>((d[col] - min_disparity) * multiplier + 0.5);
00256 index = std::min(255, std::max(0, index));
00257
00258 disparity_color_(row, col)[2] = COLOR_MAP[3*index + 0];
00259 disparity_color_(row, col)[1] = COLOR_MAP[3*index + 1];
00260 disparity_color_(row, col)[0] = COLOR_MAP[3*index + 2];
00261 }
00262 }
00263
00264 last_width_ = 0;
00265 last_height_ = 0;
00266
00267 has_image_ = true;
00268 }
00269
00270 void DisparityPlugin::PrintError(const std::string& message)
00271 {
00272 if (message == ui_.status->text().toStdString())
00273 return;
00274
00275 ROS_ERROR("Error: %s", message.c_str());
00276 QPalette p(ui_.status->palette());
00277 p.setColor(QPalette::Text, Qt::red);
00278 ui_.status->setPalette(p);
00279 ui_.status->setText(message.c_str());
00280 }
00281
00282 void DisparityPlugin::PrintInfo(const std::string& message)
00283 {
00284 if (message == ui_.status->text().toStdString())
00285 return;
00286
00287 ROS_INFO("%s", message.c_str());
00288 QPalette p(ui_.status->palette());
00289 p.setColor(QPalette::Text, Qt::green);
00290 ui_.status->setPalette(p);
00291 ui_.status->setText(message.c_str());
00292 }
00293
00294 void DisparityPlugin::PrintWarning(const std::string& message)
00295 {
00296 if (message == ui_.status->text().toStdString())
00297 return;
00298
00299 ROS_WARN("%s", message.c_str());
00300 QPalette p(ui_.status->palette());
00301 p.setColor(QPalette::Text, Qt::darkYellow);
00302 ui_.status->setPalette(p);
00303 ui_.status->setText(message.c_str());
00304 }
00305
00306 QWidget* DisparityPlugin::GetConfigWidget(QWidget* parent)
00307 {
00308 config_widget_->setParent(parent);
00309
00310 return config_widget_;
00311 }
00312
00313 bool DisparityPlugin::Initialize(QGLWidget* canvas)
00314 {
00315 canvas_ = canvas;
00316
00317 return true;
00318 }
00319
00320 void DisparityPlugin::ScaleImage(double width, double height)
00321 {
00322 if (!has_image_)
00323 {
00324 return;
00325 }
00326
00327 cv::resize(disparity_color_, scaled_image_, cvSize2D32f(width, height), 0, 0, CV_INTER_AREA);
00328 }
00329
00330 void DisparityPlugin::DrawIplImage(cv::Mat *image)
00331 {
00332
00333
00334 if (!has_image_)
00335 return;
00336
00337 if (image == NULL)
00338 return;
00339
00340 if (image->cols == 0 || image->rows == 0)
00341 return;
00342
00343 GLenum format;
00344 switch (image->channels())
00345 {
00346 case 1:
00347 format = GL_LUMINANCE;
00348 break;
00349 case 2:
00350 format = GL_LUMINANCE_ALPHA;
00351 break;
00352 case 3:
00353 format = GL_BGR;
00354 break;
00355 default:
00356 return;
00357 }
00358
00359 glPixelZoom(1.0, -1.0f);
00360 glDrawPixels(image->cols, image->rows, format, GL_UNSIGNED_BYTE, image->ptr());
00361
00362 PrintInfo("OK");
00363 }
00364
00365 void DisparityPlugin::Draw(double x, double y, double scale)
00366 {
00367
00368 double x_offset = offset_x_;
00369 double y_offset = offset_y_;
00370 double width = width_;
00371 double height = height_;
00372 if (units_ == PERCENT)
00373 {
00374 x_offset = offset_x_ * canvas_->width() / 100.0;
00375 y_offset = offset_y_ * canvas_->height() / 100.0;
00376 width = width_ * canvas_->width() / 100.0;
00377 height = height_ * canvas_->height() / 100.0;
00378 }
00379
00380
00381 if (width != last_width_ || height != last_height_)
00382 {
00383 ScaleImage(width, height);
00384 }
00385
00386
00387 double x_pos = 0;
00388 double y_pos = 0;
00389 if (anchor_ == TOP_LEFT)
00390 {
00391 x_pos = x_offset;
00392 y_pos = y_offset;
00393 }
00394 else if (anchor_ == TOP_CENTER)
00395 {
00396 x_pos = (canvas_->width() - width) / 2.0 + x_offset;
00397 y_pos = y_offset;
00398 }
00399 else if (anchor_ == TOP_RIGHT)
00400 {
00401 x_pos = canvas_->width() - width - x_offset;
00402 y_pos = y_offset;
00403 }
00404 else if (anchor_ == CENTER_LEFT)
00405 {
00406 x_pos = x_offset;
00407 y_pos = (canvas_->height() - height) / 2.0 + y_offset;
00408 }
00409 else if (anchor_ == CENTER)
00410 {
00411 x_pos = (canvas_->width() - width) / 2.0 + x_offset;
00412 y_pos = (canvas_->height() - height) / 2.0 + y_offset;
00413 }
00414 else if (anchor_ == CENTER_RIGHT)
00415 {
00416 x_pos = canvas_->width() - width - x_offset;
00417 y_pos = (canvas_->height() - height) / 2.0 + y_offset;
00418 }
00419 else if (anchor_ == BOTTOM_LEFT)
00420 {
00421 x_pos = x_offset;
00422 y_pos = canvas_->height() - height - y_offset;
00423 }
00424 else if (anchor_ == BOTTOM_CENTER)
00425 {
00426 x_pos = (canvas_->width() - width) / 2.0 + x_offset;
00427 y_pos = canvas_->height() - height - y_offset;
00428 }
00429 else if (anchor_ == BOTTOM_RIGHT)
00430 {
00431 x_pos = canvas_->width() - width - x_offset;
00432 y_pos = canvas_->height() - height - y_offset;
00433 }
00434
00435 glMatrixMode(GL_PROJECTION);
00436 glPushMatrix();
00437 glLoadIdentity();
00438 glOrtho(0, canvas_->width(), canvas_->height(), 0, -0.5f, 0.5f);
00439
00440 glRasterPos2d(x_pos, y_pos);
00441
00442 DrawIplImage(&scaled_image_);
00443
00444 glPopMatrix();
00445
00446 last_width_ = width;
00447 last_height_ = height;
00448 }
00449
00450 void DisparityPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
00451 {
00452 if (node["topic"])
00453 {
00454 std::string topic;
00455 node["topic"] >> topic;
00456 ui_.topic->setText(topic.c_str());
00457 TopicEdited();
00458 }
00459
00460 if (node["anchor"])
00461 {
00462 std::string anchor;
00463 node["anchor"] >> anchor;
00464 ui_.anchor->setCurrentIndex(ui_.anchor->findText(anchor.c_str()));
00465 SetAnchor(anchor.c_str());
00466 }
00467
00468 if (node["units"])
00469 {
00470 std::string units;
00471 node["units"] >> units;
00472 ui_.units->setCurrentIndex(ui_.units->findText(units.c_str()));
00473 SetUnits(units.c_str());
00474 }
00475
00476 if (node["offset_x"])
00477 {
00478 node["offset_x"] >> offset_x_;
00479 ui_.offsetx->setValue(static_cast<int>(offset_x_));
00480 }
00481
00482 if (node["offset_y"])
00483 {
00484 node["offset_y"] >> offset_y_;
00485 ui_.offsety->setValue(static_cast<int>(offset_y_));
00486 }
00487
00488 if (node["width"])
00489 {
00490 node["width"] >> width_;
00491 ui_.width->setValue(static_cast<int>(width_));
00492 }
00493
00494 if (node["height"])
00495 {
00496 node["height"] >> height_;
00497 ui_.height->setValue(static_cast<int>(height_));
00498 }
00499 }
00500
00501 void DisparityPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
00502 {
00503 emitter << YAML::Key << "topic" << YAML::Value << ui_.topic->text().toStdString();
00504 emitter << YAML::Key << "anchor" << YAML::Value << AnchorToString(anchor_);
00505 emitter << YAML::Key << "units" << YAML::Value << UnitsToString(units_);
00506 emitter << YAML::Key << "offset_x" << YAML::Value << offset_x_;
00507 emitter << YAML::Key << "offset_y" << YAML::Value << offset_y_;
00508 emitter << YAML::Key << "width" << YAML::Value << width_;
00509 emitter << YAML::Key << "height" << YAML::Value << height_;
00510 }
00511
00512 std::string DisparityPlugin::AnchorToString(Anchor anchor)
00513 {
00514 std::string anchor_string = "top left";
00515
00516 if (anchor == TOP_LEFT)
00517 {
00518 anchor_string = "top left";
00519 }
00520 else if (anchor == TOP_CENTER)
00521 {
00522 anchor_string = "top center";
00523 }
00524 else if (anchor == TOP_RIGHT)
00525 {
00526 anchor_string = "top right";
00527 }
00528 else if (anchor == CENTER_LEFT)
00529 {
00530 anchor_string = "center left";
00531 }
00532 else if (anchor == CENTER)
00533 {
00534 anchor_string = "center";
00535 }
00536 else if (anchor == CENTER_RIGHT)
00537 {
00538 anchor_string = "center right";
00539 }
00540 else if (anchor == BOTTOM_LEFT)
00541 {
00542 anchor_string = "bottom left";
00543 }
00544 else if (anchor == BOTTOM_CENTER)
00545 {
00546 anchor_string = "bottom center";
00547 }
00548 else if (anchor == BOTTOM_RIGHT)
00549 {
00550 anchor_string = "bottom right";
00551 }
00552
00553 return anchor_string;
00554 }
00555
00556 std::string DisparityPlugin::UnitsToString(Units units)
00557 {
00558 std::string units_string = "pixels";
00559
00560 if (units == PIXELS)
00561 {
00562 units_string = "pixels";
00563 }
00564 else if (units == PERCENT)
00565 {
00566 units_string = "percent";
00567 }
00568
00569 return units_string;
00570 }
00571
00572 const unsigned char DisparityPlugin::COLOR_MAP[768] =
00573 { 150, 150, 150,
00574 107, 0, 12,
00575 106, 0, 18,
00576 105, 0, 24,
00577 103, 0, 30,
00578 102, 0, 36,
00579 101, 0, 42,
00580 99, 0, 48,
00581 98, 0, 54,
00582 97, 0, 60,
00583 96, 0, 66,
00584 94, 0, 72,
00585 93, 0, 78,
00586 92, 0, 84,
00587 91, 0, 90,
00588 89, 0, 96,
00589 88, 0, 102,
00590 87, 0, 108,
00591 85, 0, 114,
00592 84, 0, 120,
00593 83, 0, 126,
00594 82, 0, 131,
00595 80, 0, 137,
00596 79, 0, 143,
00597 78, 0, 149,
00598 77, 0, 155,
00599 75, 0, 161,
00600 74, 0, 167,
00601 73, 0, 173,
00602 71, 0, 179,
00603 70, 0, 185,
00604 69, 0, 191,
00605 68, 0, 197,
00606 66, 0, 203,
00607 65, 0, 209,
00608 64, 0, 215,
00609 62, 0, 221,
00610 61, 0, 227,
00611 60, 0, 233,
00612 59, 0, 239,
00613 57, 0, 245,
00614 56, 0, 251,
00615 55, 0, 255,
00616 54, 0, 255,
00617 52, 0, 255,
00618 51, 0, 255,
00619 50, 0, 255,
00620 48, 0, 255,
00621 47, 0, 255,
00622 46, 0, 255,
00623 45, 0, 255,
00624 43, 0, 255,
00625 42, 0, 255,
00626 41, 0, 255,
00627 40, 0, 255,
00628 38, 0, 255,
00629 37, 0, 255,
00630 36, 0, 255,
00631 34, 0, 255,
00632 33, 0, 255,
00633 32, 0, 255,
00634 31, 0, 255,
00635 29, 0, 255,
00636 28, 0, 255,
00637 27, 0, 255,
00638 26, 0, 255,
00639 24, 0, 255,
00640 23, 0, 255,
00641 22, 0, 255,
00642 20, 0, 255,
00643 19, 0, 255,
00644 18, 0, 255,
00645 17, 0, 255,
00646 15, 0, 255,
00647 14, 0, 255,
00648 13, 0, 255,
00649 11, 0, 255,
00650 10, 0, 255,
00651 9, 0, 255,
00652 8, 0, 255,
00653 6, 0, 255,
00654 5, 0, 255,
00655 4, 0, 255,
00656 3, 0, 255,
00657 1, 0, 255,
00658 0, 4, 255,
00659 0, 10, 255,
00660 0, 16, 255,
00661 0, 22, 255,
00662 0, 28, 255,
00663 0, 34, 255,
00664 0, 40, 255,
00665 0, 46, 255,
00666 0, 52, 255,
00667 0, 58, 255,
00668 0, 64, 255,
00669 0, 70, 255,
00670 0, 76, 255,
00671 0, 82, 255,
00672 0, 88, 255,
00673 0, 94, 255,
00674 0, 100, 255,
00675 0, 106, 255,
00676 0, 112, 255,
00677 0, 118, 255,
00678 0, 124, 255,
00679 0, 129, 255,
00680 0, 135, 255,
00681 0, 141, 255,
00682 0, 147, 255,
00683 0, 153, 255,
00684 0, 159, 255,
00685 0, 165, 255,
00686 0, 171, 255,
00687 0, 177, 255,
00688 0, 183, 255,
00689 0, 189, 255,
00690 0, 195, 255,
00691 0, 201, 255,
00692 0, 207, 255,
00693 0, 213, 255,
00694 0, 219, 255,
00695 0, 225, 255,
00696 0, 231, 255,
00697 0, 237, 255,
00698 0, 243, 255,
00699 0, 249, 255,
00700 0, 255, 255,
00701 0, 255, 249,
00702 0, 255, 243,
00703 0, 255, 237,
00704 0, 255, 231,
00705 0, 255, 225,
00706 0, 255, 219,
00707 0, 255, 213,
00708 0, 255, 207,
00709 0, 255, 201,
00710 0, 255, 195,
00711 0, 255, 189,
00712 0, 255, 183,
00713 0, 255, 177,
00714 0, 255, 171,
00715 0, 255, 165,
00716 0, 255, 159,
00717 0, 255, 153,
00718 0, 255, 147,
00719 0, 255, 141,
00720 0, 255, 135,
00721 0, 255, 129,
00722 0, 255, 124,
00723 0, 255, 118,
00724 0, 255, 112,
00725 0, 255, 106,
00726 0, 255, 100,
00727 0, 255, 94,
00728 0, 255, 88,
00729 0, 255, 82,
00730 0, 255, 76,
00731 0, 255, 70,
00732 0, 255, 64,
00733 0, 255, 58,
00734 0, 255, 52,
00735 0, 255, 46,
00736 0, 255, 40,
00737 0, 255, 34,
00738 0, 255, 28,
00739 0, 255, 22,
00740 0, 255, 16,
00741 0, 255, 10,
00742 0, 255, 4,
00743 2, 255, 0,
00744 8, 255, 0,
00745 14, 255, 0,
00746 20, 255, 0,
00747 26, 255, 0,
00748 32, 255, 0,
00749 38, 255, 0,
00750 44, 255, 0,
00751 50, 255, 0,
00752 56, 255, 0,
00753 62, 255, 0,
00754 68, 255, 0,
00755 74, 255, 0,
00756 80, 255, 0,
00757 86, 255, 0,
00758 92, 255, 0,
00759 98, 255, 0,
00760 104, 255, 0,
00761 110, 255, 0,
00762 116, 255, 0,
00763 122, 255, 0,
00764 128, 255, 0,
00765 133, 255, 0,
00766 139, 255, 0,
00767 145, 255, 0,
00768 151, 255, 0,
00769 157, 255, 0,
00770 163, 255, 0,
00771 169, 255, 0,
00772 175, 255, 0,
00773 181, 255, 0,
00774 187, 255, 0,
00775 193, 255, 0,
00776 199, 255, 0,
00777 205, 255, 0,
00778 211, 255, 0,
00779 217, 255, 0,
00780 223, 255, 0,
00781 229, 255, 0,
00782 235, 255, 0,
00783 241, 255, 0,
00784 247, 255, 0,
00785 253, 255, 0,
00786 255, 251, 0,
00787 255, 245, 0,
00788 255, 239, 0,
00789 255, 233, 0,
00790 255, 227, 0,
00791 255, 221, 0,
00792 255, 215, 0,
00793 255, 209, 0,
00794 255, 203, 0,
00795 255, 197, 0,
00796 255, 191, 0,
00797 255, 185, 0,
00798 255, 179, 0,
00799 255, 173, 0,
00800 255, 167, 0,
00801 255, 161, 0,
00802 255, 155, 0,
00803 255, 149, 0,
00804 255, 143, 0,
00805 255, 137, 0,
00806 255, 131, 0,
00807 255, 126, 0,
00808 255, 120, 0,
00809 255, 114, 0,
00810 255, 108, 0,
00811 255, 102, 0,
00812 255, 96, 0,
00813 255, 90, 0,
00814 255, 84, 0,
00815 255, 78, 0,
00816 255, 72, 0,
00817 255, 66, 0,
00818 255, 60, 0,
00819 255, 54, 0,
00820 255, 48, 0,
00821 255, 42, 0,
00822 255, 36, 0,
00823 255, 30, 0,
00824 255, 24, 0,
00825 255, 18, 0,
00826 255, 12, 0,
00827 255, 6, 0,
00828 255, 0, 0,
00829 };
00830 }
00831