$search
00001 /********************************************************************* 00002 * 00003 * Software License Agreement (BSD License) 00004 * 00005 * Copyright (c) 2011, Robert Bosch LLC. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above 00015 * copyright notice, this list of conditions and the following 00016 * disclaimer in the documentation and/or other materials provided 00017 * with the distribution. 00018 * * Neither the name of the Robert Bosch nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00032 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 * POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 *********************************************************************/ 00036 #include "main_window.h" 00037 #include <iostream> 00038 #include <sstream> 00039 #include <fstream> 00040 #include <vlr/arial.h> 00041 #include <vlr/vlrException.h> 00042 #include <vlr/vlrImage.h> 00043 #include <boost/bind.hpp> 00044 #include <remote_power_manager/SetPortRelay.h> 00045 #include <opencv2/core/core.hpp> 00046 #include <opencv2/video/tracking.hpp> 00047 #include <opencv2/highgui/highgui.hpp> 00048 00049 using namespace sensor_msgs; 00050 using namespace sensor_msgs::image_encodings; 00051 using vlr::Image; 00052 using vlr::ImageBase; 00053 using vlr::TagBase; 00054 using vlr::TagPoint; 00055 using vlr::TagLine; 00056 00057 const int32_t MainWindow::catch_dist_ = 15; 00058 00059 #define DEFAULT_MODE vlr::MODE_2D 00060 #define DEFAULT_FRAMERATE 30 00061 #define DEFAULT_FORMAT QGLFormat(QGL::DoubleBuffer) 00062 00063 MainWindow::MainWindow() : 00064 width_(1024), height_(768), nh_("~"), loop_rate_(30), current_object_(NULL), current_carving_progress_(0),current_pt_(NULL), font_buffer_(NULL), action_client_("/dremel_actionserver") 00065 { 00066 00067 // Window stuff 00068 setWindowTitle(tr("PR2 Dremel")); 00069 resize(width_, height_); 00070 00071 // create central widget to display 00072 display_widget_ = new vlr::DisplayGL(this, DEFAULT_MODE, DEFAULT_FRAMERATE, DEFAULT_FORMAT); 00073 // display_widget_ = new vlr::BevGLView(this); 00074 connect(display_widget_,SIGNAL(mousePress(int, int, uint8_t)),this, SLOT(mousePress(int, int, uint8_t))); 00075 connect(display_widget_,SIGNAL(mouseRelease(int, int, uint8_t)),this, SLOT(mouseRelease(int, int, uint8_t))); 00076 connect(display_widget_,SIGNAL(mouseMove(int, int, uint8_t)),this, SLOT(mouseMove(int, int, uint8_t))); 00077 connect(display_widget_,SIGNAL(keyPress(unsigned int)),this, SLOT(keyPress(unsigned int))); 00078 connect(display_widget_,SIGNAL(mouseWheel(int, int, uint8_t, int)),this, SLOT(mouseWheel(int, int, uint8_t, int))); 00079 setCentralWidget(display_widget_); 00080 00081 // create right toolbox 00082 right_toolbox_ = new QToolBox(this); 00083 right_toolbox_->setMinimumWidth(200); 00084 QDockWidget *dock = new QDockWidget(tr("ToolBox"), this); 00085 dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); 00086 dock->setWidget(right_toolbox_); 00087 addDockWidget(Qt::RightDockWidgetArea, dock); 00088 00089 // create menu 00090 menu_widget_ = new MenuWidget(this); 00091 right_toolbox_->addItem(menu_widget_,"Carving"); 00092 00093 connect(menu_widget_->send_pushButton,SIGNAL(pressed()),this, SLOT(send())); 00094 connect(menu_widget_->cancle_pushButton,SIGNAL(pressed()),this, SLOT(cancel())); 00095 00096 connect(menu_widget_->dremel_on_pushButton,SIGNAL(pressed()),this, SLOT(enableDremel())); 00097 connect(menu_widget_->dremel_off_pushButton,SIGNAL(pressed()),this, SLOT(disableDremel())); 00098 connect(menu_widget_->vacuum_on_pushButton,SIGNAL(pressed()),this, SLOT(enableVacuum())); 00099 connect(menu_widget_->vacuum_off_pushButton,SIGNAL(pressed()),this, SLOT(disableVacuum())); 00100 00101 // initialize visualization marker 00102 current_marker_id_ = 0; 00103 viz_marker_pub_ = nh_.advertise<visualization_msgs::Marker> ("visualization_marker", 100); 00104 00105 // initialize action server 00106 ROS_INFO("waiting for action server"); 00107 action_client_.waitForServer(); 00108 ROS_INFO("found"); 00109 00110 nh_.param("fontfile", fontfile_name_, std::string("")); 00111 00112 if(!fontfile_name_.empty()) { 00113 ROS_INFO("Using fontfile: %s",fontfile_name_.c_str()); 00114 // Initialize FreeType. 00115 // font_advance_ = 0; 00116 FT_Init_FreeType(&library_); 00117 00118 std::ifstream font_file(fontfile_name_.c_str(), std::ios::binary); 00119 std::fstream::pos_type font_file_size; 00120 if (font_file) { 00121 font_file.seekg(0, std::ios::end); 00122 font_file_size = font_file.tellg(); 00123 font_file.seekg(0); 00124 font_buffer_ = new uint8_t[font_file_size]; 00125 font_file.read((char*)font_buffer_, font_file_size); 00126 } 00127 else { 00128 throw VLRException("Cannot open font file " + fontfile_name_); 00129 } 00130 FT_New_Memory_Face(library_, font_buffer_, font_file_size, 0, &face_); 00131 } 00132 else { 00133 // Initialize FreeType. 00134 FT_Init_FreeType(&library_); 00135 FT_New_Memory_Face(library_, arial_resource_data, arial_resource_size, 0, &face_); 00136 } 00137 // // TODO: remove debug 00138 // std::string filename = "/home/soeren/frame0000.jpg"; 00139 // cv::Mat img = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 00140 // 00141 // width_ = img.cols; 00142 // height_ = img.rows; 00143 img_ = new vlr::Image<uint8_t>(width_, height_); 00144 for (int32_t y = 0; y < height_; y++) { 00145 for (int32_t x = 0; x < width_; x++) { 00146 (*img_)(x, y) = 255;//img.data[y*img.step+x]; 00147 } 00148 } 00149 00150 updateImage(); 00151 } 00152 00153 MainWindow::~MainWindow() 00154 { 00155 } 00156 00157 bool MainWindow::send() 00158 { 00159 printf("about to send points\n"); 00160 std::vector<pr2_dremel_server::Segment> segments; 00161 // for each object in draw_objects_ -> accumulate to goal 00162 for(std::vector<dremel::DrawObject>::iterator it=draw_objects_.begin(); it!=draw_objects_.end();++it){ 00163 dremel::DrawObject& object = *it; 00164 std::vector<pr2_dremel_server::Segment> segment_fragment=object.convertToSegments(); 00165 segments.insert(segments.end(), segment_fragment.begin(), segment_fragment.end()); 00166 00167 } 00168 pr2_dremel_server::CarveSegmentsGoal goal_message; 00169 goal_message.segments=segments; 00170 00171 action_client_.sendGoal(goal_message, actionlib::SimpleActionClient<pr2_dremel_server::CarveSegmentsAction>::SimpleDoneCallback()); 00172 00173 action_client_.waitForResult(); 00174 00175 if (current_carving_progress_ < 1) return false; 00176 00177 return true; 00178 } 00179 00180 00181 00182 void MainWindow::cancel(){ 00183 action_client_.cancelGoal(); 00184 00185 } 00186 00187 float MainWindow::glyphToLines(wchar_t ch, int size, float outline_width, std::vector<std::vector<TagLine> >& all_lines, float initial_font_advance) { 00188 float font_advance_=initial_font_advance; 00189 // Set the size to use. 00190 if (FT_Set_Char_Size(face_, size, size, 90, 90) != 0) { 00191 throw VLRException("Failed to set font size."); 00192 } 00193 // Load the glyph we are looking for. 00194 FT_UInt gindex = FT_Get_Char_Index(face_, ch); 00195 if (FT_Load_Glyph(face_, gindex, FT_LOAD_NO_BITMAP) != 0) { 00196 throw VLRException("Failed to load glyph."); 00197 } 00198 // Need an outline for this to work. 00199 if (face_->glyph->format != FT_GLYPH_FORMAT_OUTLINE) { 00200 throw VLRException("Glyph does not contain outline information."); 00201 } 00202 00203 // Set up a stroker. 00204 FT_Stroker stroker; 00205 FT_Stroker_New(library_, &stroker); 00206 // printf("stroker var %d %d ", FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND); 00207 FT_Stroker_Set(stroker, outline_width, FT_STROKER_LINECAP_SQUARE, FT_STROKER_LINEJOIN_MITER, 0); 00208 // FT_Stroker_Set(stroker, (int) (outline_width), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); 00209 00210 FT_Glyph glyph; 00211 int32_t max_x=0; 00212 TagLine line(0, 0, 0, 0); 00213 if (FT_Get_Glyph(face_->glyph, &glyph) == 0) { 00214 FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1); 00215 // Again, this needs to be an outline to work. 00216 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { 00217 // Render the outline spans to the span list 00218 FT_Outline *o = &reinterpret_cast<FT_OutlineGlyph> (glyph)->outline; 00219 printf("Glyph contains %i contours with in total %i points.\n", o->n_contours, o->n_points); 00220 int32_t start = 0; 00221 for (int32_t c = 0; c < o->n_contours; c++) { 00222 start = (c > 0 ? o->contours[c - 1] + 1 : 0); 00223 printf("Contour %i with %i points: \n", c, o->contours[c] - start); 00224 std::vector<TagLine> lines; 00225 max_x = std::max(max_x, (int32_t)o->points[0].x); 00226 for (int32_t i = start; i < o->contours[c] - 1; i++) { 00227 printf("line (%i, %i)-(%i, %i)\n", (int)o->points[i].x, (int)o->points[i].y, (int)o->points[i + 1].x, (int)o->points[i + 1].y); 00228 line.setX0(o->points[i].x+font_advance_); 00229 line.setY0(300-o->points[i].y); 00230 line.setX1(o->points[i+1].x+font_advance_); 00231 line.setY1(300-o->points[i+1].y); 00232 lines.push_back(line); 00233 max_x = std::max(max_x, (int32_t)o->points[i+1].x); 00234 } 00235 00236 00237 line.setX0(o->points[start].x+font_advance_); 00238 line.setY0(300-o->points[start].y); 00239 line.setX1(o->points[o->contours[c] - 1].x+font_advance_); 00240 line.setY1(300-o->points[o->contours[c] - 1].y); 00241 lines.push_back(line); 00242 00243 all_lines.push_back(lines); 00244 } 00245 sendLineMarker(all_lines,std::string("/odom_combined"),1.0,1.0,1.0); 00246 } 00247 } 00248 00249 // This is unused in this test but you would need this to draw 00250 // more than one glyph. 00251 // font_advance_ += face_->glyph->advance.x; 00252 00253 // Clean up afterwards. 00254 FT_Stroker_Done(stroker); 00255 FT_Done_Glyph(glyph); 00256 00257 return max_x; // face_->glyph->advance.x; 00258 } 00259 00260 void MainWindow::sendLineMarker(std::vector<std::vector<TagLine> >& lines, std::string frame_id, double r, double g, double b) { 00261 lines_marker_.ns = "draw_gcode"; 00262 lines_marker_.header.frame_id = frame_id; 00263 lines_marker_.type = visualization_msgs::Marker::LINE_STRIP; 00264 lines_marker_.action = visualization_msgs::Marker::ADD; 00265 lines_marker_.scale.x = lines_marker_.scale.y = lines_marker_.scale.z = 1; 00266 lines_marker_.color.a = 1.0; 00267 lines_marker_.color.r = r; 00268 lines_marker_.color.g = g; 00269 lines_marker_.color.b = b; 00270 00271 for(std::vector<std::vector<TagLine> >::iterator it=lines.begin();it!=lines.end();++it) { 00272 std::vector<TagLine>& line_segment = *it; 00273 std::vector<geometry_msgs::Point> points; 00274 for(std::vector<TagLine>::iterator itT=line_segment.begin();itT!=line_segment.end();++itT) { 00275 TagLine& line = *itT; 00276 geometry_msgs::Point p0,p1; 00277 p0.x = line.x0(); 00278 p0.y = line.y0(); 00279 points.push_back(p0); 00280 p1.x = line.x1(); 00281 p1.y = line.y1(); 00282 points.push_back(p1); 00283 } 00284 lines_marker_.points = points; 00285 lines_marker_.id = current_marker_id_++; 00286 lines_marker_.header.stamp = ros::Time::now(); 00287 viz_marker_pub_.publish(lines_marker_); 00288 } 00289 return; 00290 } 00291 00292 void MainWindow::linesToGcode(std::vector<std::vector<vlr::TagLine> >& lines) { 00293 00294 std::string gcode_string= "%\n(Generated by gcodetools from inkscape.)\nM3\n(Header end.)\nG21 (All units in mm)\n\n"; 00295 00296 00297 00298 int num_separate_contours=lines.size(); 00299 00300 //for each set of contours 00301 00302 for (int contour_ind = 0; contour_ind < num_separate_contours; contour_ind++) { 00303 int numlines=lines.at(contour_ind).size(); 00304 //for segments within the coutour 00305 for (int line_index = 0; line_index < numlines; line_index++) { 00306 std::ostringstream buffer_x0; 00307 std::ostringstream buffer_x1; 00308 std::ostringstream buffer_y0; 00309 std::ostringstream buffer_y1; 00310 buffer_x0 << lines.at(contour_ind).at(line_index).x0()/10; 00311 buffer_x1 << lines.at(contour_ind).at(line_index).x1()/10; 00312 buffer_y0 << lines.at(contour_ind).at(line_index).y0()/10; 00313 buffer_y1 << lines.at(contour_ind).at(line_index).y1()/10; 00314 00315 std::string x0_string = buffer_x0.str(); 00316 std::string x1_string = buffer_x1.str(); 00317 std::string y0_string = buffer_y0.str(); 00318 std::string y1_string = buffer_y1.str(); 00319 00320 if(line_index==0){ 00321 gcode_string=gcode_string + "G00 Z5.00\nG00 X" + x0_string + " Y" + y0_string+ "\n\nG01 Z-0.1000 F100.0\n"; 00322 gcode_string=gcode_string + "G01 X" + x1_string + " Y" + y1_string+ " Z-0.1000 F400.0\n"; 00323 } 00324 else{ 00325 gcode_string=gcode_string + "G01 X" + x0_string + " Y" + y0_string+ " Z-0.1000\n"; 00326 gcode_string=gcode_string + "G01 X" + x1_string + " Y" + y1_string+ " Z-0.1000\n"; 00327 } 00328 } 00329 gcode_string=gcode_string+"G00 Z5.0\n\n"; 00330 } 00331 00332 00333 gcode_string=gcode_string+"(Footer)\nM5\nG00 X0.00 Y0.00\nM2\n(Using default footer.)\n(end)\n%"; 00334 std::string filename="test_gcode_file"; 00335 std::FILE *fp; 00336 00337 fp=fopen(filename.c_str(), "w"); 00338 fprintf(fp, "%s", gcode_string.c_str()); 00339 fclose(fp); 00340 } 00341 00342 std::pair<dremel::DrawObject*,float> MainWindow::getClosestObject(float x, float y) { 00343 std::pair<dremel::DrawObject*,float> closest_object; 00344 closest_object.first = NULL; 00345 closest_object.second = FLT_MAX; 00346 float dist; 00347 00348 for(std::vector<dremel::DrawObject>::iterator itO=draw_objects_.begin();itO!=draw_objects_.end();++itO) { 00349 dremel::DrawObject& object = *itO; 00350 std::vector<std::vector<vlr::TagLine> >& lines = object.getLines(); 00351 for(std::vector<std::vector<vlr::TagLine> >::iterator itL=lines.begin();itL!=lines.end();++itL) { 00352 std::vector<vlr::TagLine>& tag_lines = *itL; 00353 for(std::vector<vlr::TagLine>::iterator itT=tag_lines.begin();itT!=tag_lines.end();++itT) { 00354 vlr::TagLine& tag_line = *itT; 00355 dist = sqrt( (tag_line.x0() - x)*(tag_line.x0() - x) + (tag_line.y0() - y)*(tag_line.y0() - y) ); 00356 if(dist<closest_object.second) { 00357 closest_object.first = &object; 00358 closest_object.second = dist; 00359 } 00360 dist = sqrt( (tag_line.x1() - x)*(tag_line.x1() - x) + (tag_line.y1() - y)*(tag_line.y1() - y) ); 00361 if(dist<closest_object.second) { 00362 closest_object.first = &object; 00363 closest_object.second = dist; 00364 } 00365 } 00366 } 00367 } 00368 return closest_object; 00369 } 00370 00371 void MainWindow::moveDrawObject(dremel::DrawObject* object, int dx, int dy) { 00372 00373 object->move(dx,dy); 00374 updateImage(); 00375 } 00376 00377 void MainWindow::scaleDrawObject(dremel::DrawObject* object, float scale) { 00378 00379 object->scale(scale); 00380 updateImage(); 00381 } 00382 00383 void MainWindow::eraseObject(dremel::DrawObject* object) { 00384 int n=0; 00385 bool found = false; 00386 for(std::vector<dremel::DrawObject>::iterator itO=draw_objects_.begin();itO!=draw_objects_.end();++itO,n++) { 00387 dremel::DrawObject& object = *itO; 00388 if(current_object_ == &object) { 00389 found = true; 00390 break; 00391 } 00392 } 00393 if(found) { 00394 draw_objects_.erase(draw_objects_.begin()+n); 00395 updateImage(); 00396 } 00397 } 00398 00399 00400 void MainWindow::mouseMove(int x, int y, uint8_t buttons) { 00401 00402 if (buttons & vlr::LEFT_BUTTON) { 00403 if (current_object_) { 00404 int dx = x-last_move_x_; 00405 int dy = y-last_move_y_; 00406 moveDrawObject(current_object_,dx,dy); 00407 last_move_x_ = x; 00408 last_move_y_ = y; 00409 } 00410 } 00411 00412 else { 00413 // find close object 00414 std::pair<dremel::DrawObject*,float> closest_object = getClosestObject(x,y); 00415 std::cout << closest_object.second << std::endl; 00416 if(closest_object.second < catch_dist_) { 00417 QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor)); 00418 } 00419 else { 00420 QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); 00421 } 00422 } 00423 } 00424 00425 void MainWindow::mousePress(int x, int y, uint8_t buttons) { 00426 printf("%s\n", __PRETTY_FUNCTION__); 00427 printf("x: %i, y: %i\n", x, y); 00428 if (buttons & vlr::LEFT_BUTTON) { 00429 00430 // deselect old point pair 00431 if (current_object_) { 00432 current_object_->changeSelected(false); 00433 } 00434 00435 // find close object 00436 std::pair<dremel::DrawObject*,float> closest_object = getClosestObject(x,y); 00437 std::cout << closest_object.second << std::endl; 00438 if(closest_object.second < catch_dist_) { 00439 current_object_ = closest_object.first; 00440 current_object_->changeSelected(true); 00441 std::cout << "selected object" << std::endl; 00442 } 00443 else { 00444 current_object_ = NULL; 00445 std::cout << "removed selection" << std::endl; 00446 } 00447 00448 last_move_x_ = x; 00449 last_move_y_ = y; 00450 00451 updateImage(); 00452 } 00453 else if(buttons & vlr::RIGHT_BUTTON){ 00454 printf("Right button clicked"); 00455 std::vector<std::vector<vlr::TagLine> > templines; 00456 if(!current_object_) 00457 { 00458 //create a set of empty lines to create the object(we only know a point thus far) 00459 printf("start a new draw object line"); 00460 dremel::DrawObject object(templines); 00461 object.setAsNotText(); 00462 draw_objects_.push_back(object); 00463 current_object_=&draw_objects_.back(); 00464 00465 last_right_x_=x; 00466 last_right_y_=y; 00467 00468 } 00469 else if(current_object_ && !current_object_->isText()) 00470 { 00471 printf("add to existing line"); 00472 00473 //create the lines given last values and x,y and save 00474 00475 std::vector<vlr::TagLine> newline_vector; 00476 vlr::TagLine newline(last_right_x_, last_right_y_, x, y); 00477 newline_vector.push_back(newline); 00478 templines.push_back(newline_vector); 00479 current_object_->insertNewLines(templines); 00480 00481 last_right_x_=x; 00482 last_right_y_=y; 00483 //update Image here 00484 updateImage(); 00485 } 00486 00487 } 00488 00489 } 00490 00491 void MainWindow::mouseRelease(int x, int y, uint8_t buttons) { 00492 printf("x: %i, y: %i\n", x, y); 00493 if (buttons & vlr::LEFT_BUTTON) { 00494 std::pair<ImageBase::tagCIter, ImageBase::tagCIter> ptRange; 00495 ImageBase::tagCIter ptit; 00496 img_->points(ptRange); 00497 00498 // deselect old point pair 00499 if (current_pt_) { 00500 current_pt_->setRGB(1.0, 0.0, 0.0); 00501 } 00502 00503 bool newPoint = true; 00504 00505 for (ptit = ptRange.first; ptit != ptRange.second; ++ptit) { 00506 TagPoint* pt = static_cast<TagPoint*> ((*ptit).second); 00507 float xf = (float) x; 00508 float yf = (float) y; 00509 if ((xf - pt->x()) * (xf - pt->x()) + (yf - pt->y()) * (yf - pt->y()) < catch_dist_ * catch_dist_) { 00510 newPoint = false; 00511 current_pt_ = static_cast<TagPoint*> ((*ptit).second); 00512 if (current_pt_) { 00513 current_pt_->setRGB(0.0, 1.0, 0.0); 00514 } 00515 break; 00516 } 00517 } 00518 00519 if (newPoint) { 00520 std::stringstream label; 00521 label << "(" << x << ", " << y << ")"; 00522 current_pt_ = img_->addPoint(x, y, label.str(), 0, 1, 0, 1); 00523 } 00524 00525 updateImage(); 00526 } 00527 } 00528 00529 void MainWindow::keyPress(unsigned int key) { 00530 printf("keycode %d\n", key); 00531 switch (key) { 00532 // case 29: 00533 // doneWithImage=true; 00534 // break; 00535 // 00536 // case 31: { 00537 // } 00538 // break; 00539 case 0:{//shift 00540 printf("shifted!"); 00541 } 00542 break; 00543 00544 case 13:{//enter key return 00545 //first add the current lines to a drawobject 00546 dremel::DrawObject object(lines_); 00547 draw_objects_.push_back(object); 00548 printf("size of draw_objects_ %d\n current object has lines_ with size %d", (int) draw_objects_.size(), (int) lines_.size()); 00549 00550 //now clear lines for the next set 00551 // lines_ = new std::vector<std::vector<vlr::TagLine>>; 00552 lines_.clear(); 00553 } 00554 break; 00555 case ' ': { 00556 } 00557 break; 00558 case 8: { 00559 if(current_object_) { 00560 eraseObject(current_object_); 00561 current_object_ = NULL; 00562 } 00563 break; 00564 } 00565 default: 00566 00567 00568 lines_.clear(); 00569 00570 float curr_font_advance=0; 00571 00572 if (current_object_ == NULL || !current_object_->isText()) { 00573 curr_font_advance = glyphToLines(key, 100, 0.0f, lines_, 0); 00574 dremel::DrawObject object(lines_); 00575 object.changeSelected(true); 00576 draw_objects_.push_back(object); 00577 current_object_=&draw_objects_.back(); 00578 current_object_->addToFontAdvance(curr_font_advance); 00579 00580 } 00581 else{ 00582 float initial_font_advance=current_object_->getFontAdvance(); 00583 curr_font_advance=glyphToLines(key, 100, 0.0f, lines_, initial_font_advance); 00584 printf("additional font advance %f", curr_font_advance); 00585 00586 current_object_->insertNewLines(lines_); 00587 current_object_->addToFontAdvance(curr_font_advance); 00588 } 00589 00590 00591 00592 // lines_.clear(); 00593 // curr_font_advance+=glyphToLines(key, 100, 3.0f, lines_); 00594 // if(!lines_.empty()) { 00595 // //linesToGcode(lines_); 00596 // addCountoursToImage(lines_); 00597 // } 00598 updateImage(); 00599 } 00600 } 00601 00602 void MainWindow::mouseWheel(int x, int y, uint8_t buttons, int delta) { 00603 if (current_object_) { 00604 float scale = 1.0 + delta*0.001; 00605 scaleDrawObject(current_object_,scale); 00606 } 00607 } 00608 00609 void MainWindow::addCountoursToImage(std::vector<std::vector<vlr::TagLine> >& contours) { 00610 // for each set of contours 00611 for (size_t i=0; i<contours.size(); i++) { 00612 std::vector<vlr::TagLine>& lines = contours[i]; 00613 // for segments within the coutour 00614 for(size_t j=0; j<lines.size(); j++) { 00615 vlr::TagLine& tl = lines[j]; 00616 vlr::TagLine* tl_ptr = new vlr::TagLine(tl.x0(),tl.y0(),tl.x1(),tl.y1()); 00617 img_->addTag(tl_ptr); 00618 } 00619 } 00620 display_widget_->updateImage(*img_); 00621 } 00622 00623 void MainWindow::updateImage() { 00624 00625 img_->clearTags(); 00626 00627 for(std::vector<dremel::DrawObject>::iterator itO=draw_objects_.begin();itO!=draw_objects_.end();++itO) { 00628 dremel::DrawObject& object = *itO; 00629 std::vector<std::vector<vlr::TagLine> >& lines = object.getLines(); 00630 for(std::vector<std::vector<vlr::TagLine> >::iterator itL=lines.begin();itL!=lines.end();++itL) { 00631 std::vector<vlr::TagLine>& tag_lines = *itL; 00632 for(std::vector<vlr::TagLine>::iterator itT=tag_lines.begin();itT!=tag_lines.end();++itT) { 00633 vlr::TagLine& tl = *itT; 00634 vlr::TagLine* tl_ptr = new vlr::TagLine(tl.x0(),tl.y0(),tl.x1(),tl.y1()); 00635 if(object.isSelected()) { 00636 tl_ptr->setRGB(1.0,0.0,0.0); 00637 } 00638 else { 00639 tl_ptr->setRGB(0.0,0.0,0.0); 00640 } 00641 img_->addTag(tl_ptr); 00642 } 00643 } 00644 } 00645 display_widget_->updateImage(*img_); 00646 } 00647 00648 void MainWindow::enableDremel() { 00649 ros::ServiceClient client = nh_.serviceClient<remote_power_manager::SetPortRelay>("/remote_power_manager/set_port_relay"); 00650 remote_power_manager::SetPortRelay::Request req; 00651 remote_power_manager::SetPortRelay::Response resp; 00652 req.power_port = 1; 00653 req.value = true; 00654 if (client.call(req,resp)) 00655 { 00656 ROS_INFO("Enabled dremel!!"); 00657 } 00658 } 00659 00660 void MainWindow::disableDremel() { 00661 ros::ServiceClient client = nh_.serviceClient<remote_power_manager::SetPortRelay>("/remote_power_manager/set_port_relay"); 00662 remote_power_manager::SetPortRelay::Request req; 00663 remote_power_manager::SetPortRelay::Response resp; 00664 req.power_port = 1; 00665 req.value = false; 00666 if (client.call(req,resp)) 00667 { 00668 ROS_INFO("Disabled dremel!!"); 00669 } 00670 } 00671 00672 void MainWindow::enableVacuum() { 00673 ros::ServiceClient client = nh_.serviceClient<remote_power_manager::SetPortRelay>("/remote_power_manager/set_port_relay"); 00674 remote_power_manager::SetPortRelay::Request req; 00675 remote_power_manager::SetPortRelay::Response resp; 00676 req.power_port = 2; 00677 req.value = true; 00678 if (client.call(req,resp)) 00679 { 00680 ROS_INFO("Enabled vacuum!!"); 00681 } 00682 } 00683 00684 void MainWindow::disableVacuum() { 00685 ros::ServiceClient client = nh_.serviceClient<remote_power_manager::SetPortRelay>("/remote_power_manager/set_port_relay"); 00686 remote_power_manager::SetPortRelay::Request req; 00687 remote_power_manager::SetPortRelay::Response resp; 00688 req.power_port = 2; 00689 req.value = false; 00690 if (client.call(req,resp)) 00691 { 00692 ROS_INFO("Disabled vacuum!!"); 00693 } 00694 } 00695 00696 00697 // 00698 // 00700 //btVector2 MainWindow::normalizePixel(const btVector2& x_kk,fc,cc,kc,alpha_c) 00701 //{ 00702 // K = basic_compose_k_matrix(calib_results.fc, calib_results.cc, calib_results.alpha_c); 00703 // 00704 //} 00705 // 00707 //void MainWindow::unprojectPixel(const tf::Transform& camera_transform, const btVector2& pixel, const btVector3& point) 00708 //{ 00709 // K = basic_compose_k_matrix(calib_results.fc, calib_results.cc, calib_results.alpha_c); 00710 // 00711 //} 00712 // 00713 // 00714 //void MainWindow::calculateWorkArea(const tf::Transform& camera_transform, std::string& target_frame, btVector3& points[4]) 00715 //{ 00716 // btVector3 n(0, 0, 1); 00717 // btPlane table(n, table_height_); // TODO: table height is probably measured from floor and not from base_link origin 00718 // btVector3 o = camera_transform.getOrigin(); // origin of camera 00719 // btVector3 p = o + camera_transform.getBasis()*btVector3(0, 0, 1); // point along optical axis of camera to determine view direction 00720 // 00721 //} 00722 // 00723 //tf::Transform MainWindow::getPlaneTransform () 00724 //{ 00725 // //assume plane coefficients are normalized 00726 // btVector3 position(); 00727 // btVector3 z(a, b, c); 00728 // //make sure z points "down" 00729 // ROS_DEBUG("z.dot: %0.3f", z.dot(btVector3(0,0,1))); 00730 // ROS_DEBUG("in getPlaneTransform, z: %0.3f, %0.3f, %0.3f", z[0], z[1], z[2]); 00731 // if ( z.dot( btVector3(0, 0, up_direction) ) < 0) 00732 // { 00733 // z = -1.0 * z; 00734 // ROS_INFO("flipped z"); 00735 // } 00736 // ROS_DEBUG("in getPlaneTransform, z: %0.3f, %0.3f, %0.3f", z[0], z[1], z[2]); 00737 // 00738 // //try to align the x axis with the x axis of the original frame 00739 // //or the y axis if z and x are too close too each other 00740 // btVector3 x(1, 0, 0); 00741 // if ( fabs(z.dot(x)) > 1.0 - 1.0e-4) x = btVector3(0, 1, 0); 00742 // btVector3 y = z.cross(x).normalized(); 00743 // x = y.cross(z).normalized(); 00744 // 00745 // btMatrix3x3 rotation; 00746 // rotation[0] = x; // x 00747 // rotation[1] = y; // y 00748 // rotation[2] = z; // z 00749 // rotation = rotation.transpose(); 00750 // btQuaternion orientation; 00751 // rotation.getRotation(orientation); 00752 // return tf::Transform(orientation, position); 00753 //} 00754