00001
00008
00009
00010
00011
00012 #include <QtGui>
00013 #include <QMessageBox>
00014 #include <iostream>
00015 #include "../include/tibi_dabo_sequence_editor/main_window.hpp"
00016
00017 #include "eventexceptions.h"
00018 #include "motor_control_exceptions.h"
00019 #include "motor_config.h"
00020
00021
00022
00023
00024
00025 namespace tibi_dabo_sequence_editor {
00026
00027 using namespace Qt;
00028
00029
00030
00031
00032
00033 MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
00034 : QMainWindow(parent)
00035 , qnode(argc,argv)
00036 {
00037 QStringList headers;
00038 QString joint,value;
00039 unsigned int i=0;
00040
00041
00042 this->event_server=CEventServer::instance();
00043 this->motion_file_name="";
00044 this->current_step=0;
00045 this->seq.clear();
00046
00047
00048 ui.setupUi(this);
00049 QObject::connect(ui.actionAbout_Qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt()));
00050 QObject::connect(ui.motion_steps, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(on_motion_step_changed()));
00051
00052
00053 this->min_pos_text[0]=this->ui.min_pos_text_1;
00054 this->min_pos_text[1]=this->ui.min_pos_text_2;
00055 this->min_pos_text[2]=this->ui.min_pos_text_5;
00056 this->min_pos_text[3]=this->ui.min_pos_text_6;
00057 this->min_pos_text[4]=this->ui.min_pos_text_7;
00058 this->min_pos_text[5]=this->ui.min_pos_text_8;
00059 this->max_pos_text[0]=this->ui.max_pos_text_1;
00060 this->max_pos_text[1]=this->ui.max_pos_text_2;
00061 this->max_pos_text[2]=this->ui.max_pos_text_5;
00062 this->max_pos_text[3]=this->ui.max_pos_text_6;
00063 this->max_pos_text[4]=this->ui.max_pos_text_7;
00064 this->max_pos_text[5]=this->ui.max_pos_text_8;
00065 this->min_vel_text[0]=this->ui.min_vel_text_1;
00066 this->min_vel_text[1]=this->ui.min_vel_text_2;
00067 this->min_vel_text[2]=this->ui.min_vel_text_5;
00068 this->min_vel_text[3]=this->ui.min_vel_text_6;
00069 this->min_vel_text[4]=this->ui.min_vel_text_7;
00070 this->min_vel_text[5]=this->ui.min_vel_text_8;
00071 this->max_vel_text[0]=this->ui.max_vel_text_1;
00072 this->max_vel_text[1]=this->ui.max_vel_text_2;
00073 this->max_vel_text[2]=this->ui.max_vel_text_5;
00074 this->max_vel_text[3]=this->ui.max_vel_text_6;
00075 this->max_vel_text[4]=this->ui.max_vel_text_7;
00076 this->max_vel_text[5]=this->ui.max_vel_text_8;
00077 this->desired_pos[0]=this->ui.desired_pos_1;
00078 this->desired_pos[1]=this->ui.desired_pos_2;
00079 this->desired_pos[2]=this->ui.desired_pos_5;
00080 this->desired_pos[3]=this->ui.desired_pos_6;
00081 this->desired_pos[4]=this->ui.desired_pos_7;
00082 this->desired_pos[5]=this->ui.desired_pos_8;
00083 this->desired_vel[0]=this->ui.desired_vel_1;
00084 this->desired_vel[1]=this->ui.desired_vel_2;
00085 this->desired_vel[2]=this->ui.desired_vel_5;
00086 this->desired_vel[3]=this->ui.desired_vel_6;
00087 this->desired_vel[4]=this->ui.desired_vel_7;
00088 this->desired_vel[5]=this->ui.desired_vel_8;
00089 this->desired_pos_value[0]=this->ui.desired_pos_value_1;
00090 this->desired_pos_value[1]=this->ui.desired_pos_value_2;
00091 this->desired_pos_value[2]=this->ui.desired_pos_value_5;
00092 this->desired_pos_value[3]=this->ui.desired_pos_value_6;
00093 this->desired_pos_value[4]=this->ui.desired_pos_value_7;
00094 this->desired_pos_value[5]=this->ui.desired_pos_value_8;
00095 this->desired_vel_value[0]=this->ui.desired_vel_value_1;
00096 this->desired_vel_value[1]=this->ui.desired_vel_value_2;
00097 this->desired_vel_value[2]=this->ui.desired_vel_value_5;
00098 this->desired_vel_value[3]=this->ui.desired_vel_value_6;
00099 this->desired_vel_value[4]=this->ui.desired_vel_value_7;
00100 this->desired_vel_value[5]=this->ui.desired_vel_value_8;
00101 this->position_text[0]=this->ui.position_text_1;
00102 this->position_text[1]=this->ui.position_text_2;
00103 this->position_text[2]=this->ui.position_text_3;
00104 this->position_text[3]=this->ui.position_text_4;
00105 this->position_text[4]=this->ui.position_text_5;
00106 this->position_text[5]=this->ui.position_text_6;
00107 this->velocity_text[0]=this->ui.velocity_text_1;
00108 this->velocity_text[1]=this->ui.velocity_text_2;
00109 this->velocity_text[2]=this->ui.velocity_text_3;
00110 this->velocity_text[3]=this->ui.velocity_text_4;
00111 this->velocity_text[4]=this->ui.velocity_text_5;
00112 this->velocity_text[5]=this->ui.velocity_text_6;
00113
00114 this->load_joints_config();
00115
00116
00117 for(i=0;i<this->dof;i++)
00118 config_joint(i,true,this->min_pos[0],this->max_pos[0],this->min_vel[0],this->max_vel[0]);
00119
00120 this->ui.motion_steps->setSortingEnabled(false);
00121 this->ui.motion_steps->setColumnCount(2+this->dof*2);
00122 headers.push_back("step no.");
00123 for(i=0;i<this->dof;i++)
00124 {
00125 joint.setNum(i);
00126 headers.push_back("joint " + joint + " pos");
00127 headers.push_back("joint " + joint + " vel");
00128 }
00129 headers.push_back("delay");
00130 this->ui.motion_steps->setHorizontalHeaderLabels(headers);
00131 this->ui.motion_steps->setSelectionBehavior(QAbstractItemView::SelectRows);
00132 this->ui.motion_steps->setSelectionMode(QAbstractItemView::SingleSelection);
00133 value.setNum(this->seq.size());
00134 this->ui.num_steps->setText(value);
00135 value.setNum(0);
00136 this->ui.delay->setText(value);
00137
00138
00139 this->startTimer(100);
00140 }
00141
00142 MainWindow::~MainWindow()
00143 {
00144 this->seq.clear();
00145 }
00146
00147 void MainWindow::timerEvent(QTimerEvent * event)
00148 {
00149
00150 if(this->event_server->event_is_set(this->qnode.get_action_feedback_event_id()))
00151 {
00152 this->ui.get_current->click();
00153 this->event_server->reset_event(this->qnode.get_action_feedback_event_id());
00154 }
00155 }
00156
00157 void MainWindow::config_joint(int index,bool enable,float min_pos,float max_pos,float min_vel, float max_vel)
00158 {
00159 QString value;
00160
00161 this->position_text[index]->setEnabled(enable);
00162 this->velocity_text[index]->setEnabled(enable);
00163 this->desired_pos[index]->setEnabled(enable);
00164 this->desired_vel[index]->setEnabled(enable);
00165 this->desired_pos_value[index]->setEnabled(enable);
00166 this->desired_vel_value[index]->setEnabled(enable);
00167 this->min_pos_text[index]->setEnabled(enable);
00168 value.setNum(min_pos);
00169 this->min_pos_text[index]->setText(value);
00170 this->max_pos_text[index]->setEnabled(enable);
00171 value.setNum(max_pos);
00172 this->max_pos_text[index]->setText(value);
00173 this->min_vel_text[index]->setEnabled(enable);
00174 value.setNum(min_vel);
00175 this->min_vel_text[index]->setText(value);
00176 this->max_vel_text[index]->setEnabled(enable);
00177 value.setNum(max_vel);
00178 this->max_vel_text[index]->setText(value);
00179 this->desired_pos[index]->setRange(min_pos,max_pos);
00180 this->desired_vel[index]->setRange(min_vel,max_vel);
00181 }
00182
00183 void MainWindow::load_joints_config(void)
00184 {
00185 motor_config_t::axis_config_iterator iterator;
00186 std::vector<std::string> config_files;
00187 std::string config_file_full_path;
00188 unsigned int i=0;
00189
00190 config_files=this->qnode.get_config_files();
00191 this->dof=0;
00192 try{
00193 for(i=0;i<config_files.size();i++)
00194 {
00195 std::auto_ptr<motor_config_t> cfg(motor_config(config_files[i].c_str(),xml_schema::flags::dont_validate));
00196 this->dof+=cfg->num_axis();
00197 for(iterator=cfg->axis_config().begin();iterator!=cfg->axis_config().end();iterator++)
00198 {
00199 this->min_vel.push_back(iterator->velocity_range().min());
00200 this->max_vel.push_back(iterator->velocity_range().max());
00201 this->min_pos.push_back(iterator->position_range().min());
00202 this->max_pos.push_back(iterator->position_range().max());
00203 }
00204 }
00205 }catch (const xml_schema::exception& e){
00206
00207 std::ostringstream os;
00208 os << e;
00209 QMessageBox msgBox;
00210 msgBox.setText(QString(os.str().c_str()));
00211 msgBox.setIcon(QMessageBox::Warning);
00212 msgBox.exec();
00213 }
00214
00215
00216 }
00217
00218 void MainWindow::fill_motion_table(void)
00219 {
00220 unsigned int i=0,num_row;
00221 QString value;
00222
00223
00224 num_row=this->ui.motion_steps->rowCount();
00225 for(i=0;i<num_row;i++)
00226 this->ui.motion_steps->removeRow(0);
00227 value.setNum(0);
00228 this->ui.num_steps->setText(value);
00229 for(i=0;i<this->seq.size();i++)
00230 this->add_motion_step(this->seq[i].position,this->seq[i].velocity,this->seq[i].delay);
00231 }
00232
00233 void MainWindow::add_motion_step(std::vector<float> position, std::vector<float> velocity, float delay)
00234 {
00235 QTableWidgetItem *item;
00236 unsigned int row,i;
00237 QString value;
00238
00239 row=this->ui.motion_steps->rowCount();
00240 this->ui.motion_steps->setRowCount(row+1);
00241 value.setNum(row);
00242 item=new QTableWidgetItem(value);
00243 this->ui.motion_steps->setItem(row,0,item);
00244 value.setNum(delay);
00245 item=new QTableWidgetItem(value);
00246 this->ui.motion_steps->setItem(row,2*this->dof+1,item);
00247 for(i=0;i<position.size();i++)
00248 {
00249 value.setNum(position[i]);
00250 item=new QTableWidgetItem(value);
00251 this->ui.motion_steps->setItem(row,2*i+1,item);
00252 value.setNum(velocity[i]);
00253 item=new QTableWidgetItem(value);
00254 this->ui.motion_steps->setItem(row,2*i+2,item);
00255 }
00256 value.setNum(row+1);
00257 this->ui.num_steps->setText(value);
00258 }
00259
00260
00261
00262
00263
00264 void MainWindow::on_get_current_clicked()
00265 {
00266 std::list<std::string> events;
00267 std::vector<float> current_pos;
00268 std::vector<float> current_vel;
00269 unsigned int i=0;
00270 QString value;
00271
00272 events.push_back(this->qnode.get_new_feedback_event_id());
00273 try{
00274 this->event_server->wait_all(events,1000);
00275 this->qnode.get_motion_feedback(current_pos,current_vel);
00276 for(i=0;i<current_pos.size();i++)
00277 {
00278 this->desired_pos[i]->setValue(current_pos[i]*180.0/3.14159);
00279 value.setNum(current_pos[i]*180.0/3.14159);
00280 this->desired_pos_value[i]->setText(value);
00281 this->desired_vel[i]->setValue(current_vel[i]*180.0/3.14159);
00282 value.setNum(current_vel[i]*180.0/3.14159);
00283 this->desired_vel_value[i]->setText(value);
00284 }
00285 this->event_server->reset_event(this->qnode.get_new_feedback_event_id());
00286 }catch(CEventTimeoutException &e){
00287
00288 QMessageBox msgBox;
00289 msgBox.setText("No connection to the node");
00290 msgBox.setIcon(QMessageBox::Warning);
00291 msgBox.exec();
00292 }
00293 }
00294
00295 void MainWindow::on_load_sequence_clicked()
00296 {
00297 QString caption("Open motion sequence file"),directory("."),filter("*.xml"),filename;
00298 std::string control_mode, motion_mode;
00299 sequence_t::step_iterator iterator;
00300 QFileDialog *open_file;
00301 QStringList file_list;
00302 unsigned int num=0;
00303 TMotionStep step;
00304
00305 open_file=new QFileDialog(this,caption,directory,filter);
00306
00307 if(open_file->exec())
00308 {
00309 file_list=open_file->selectedFiles();
00310 if(file_list.size()==1)
00311 {
00312 try{
00313 filename=file_list.at(0);
00314 this->motion_file_name=file_list.at(0).toLocal8Bit().constData();
00315 this->ui.sequence_name->setText(filename.toAscii().data());
00316 std::cout << filename.toAscii().data() << std::endl;
00317 std::auto_ptr<sequence_t> seq(motion_seq(filename.toAscii().data(),xml_schema::flags::dont_validate));
00318 if((num=seq->num_motors())!=this->dof)
00319 {
00320
00321 throw CMotionSequenceException(_HERE_,"The number of motors in the loaded sequence does not coincide with the number of motors in the associated motor groupY");
00322 }
00323 else
00324 {
00325
00326 num=seq->num_steps();
00327
00328 control_mode=seq->control();
00329
00330 if(control_mode=="position")
00331 {
00332 this->ui.position_control->setChecked(true);
00333 this->ui.velocity_control->setChecked(false);
00334 }
00335 else
00336 {
00337 this->ui.position_control->setChecked(false);
00338 this->ui.velocity_control->setChecked(true);
00339 }
00340
00341 motion_mode=seq->motion();
00342
00343 if(motion_mode=="absolute")
00344 {
00345 this->ui.absolute_motion->setChecked(true);
00346 this->ui.relative_motion->setChecked(false);
00347 }
00348 else
00349 {
00350 this->ui.absolute_motion->setChecked(false);
00351 this->ui.relative_motion->setChecked(true);
00352 }
00353
00354 this->seq.clear();
00355 for(iterator=seq->step().begin();iterator!=seq->step().end();iterator++)
00356 {
00357 step.delay=iterator->delay();
00358 step.position.clear();
00359 step.velocity.clear();
00360 step.position=iterator->position();
00361 step.velocity=iterator->velocity();
00362 this->seq.push_back(step);
00363 }
00364 this->fill_motion_table();
00365 this->ui.motion_steps->selectRow(0);
00366 }
00367 }catch (const xml_schema::exception& e){
00368
00369 std::ostringstream os;
00370 os << e;
00371 QMessageBox msgBox;
00372 msgBox.setText(QString(os.str().c_str()));
00373 msgBox.setIcon(QMessageBox::Warning);
00374 msgBox.exec();
00375 }
00376 }
00377 }
00378 delete open_file;
00379 }
00380
00381 void MainWindow::on_save_sequence_clicked()
00382 {
00383 if(this->ui.sequence_name->text().size()!=0)
00384 {
00385
00386 this->motion_file_name=this->ui.sequence_name->text().toLocal8Bit().constData();
00387 }
00388 else
00389 {
00390 QMessageBox msgBox;
00391 msgBox.setText("No filename specified. Impossible to create a new motion sequence file.");
00392 msgBox.setIcon(QMessageBox::Warning);
00393 msgBox.exec();
00394 }
00395
00396 }
00397
00398 void MainWindow::on_create_sequence_clicked()
00399 {
00400 QString filename;
00401
00402
00403 this->seq.clear();
00404 this->current_step=0;
00405 this->fill_motion_table();
00406 }
00407
00408 void MainWindow::on_execute_sequence_clicked()
00409 {
00410 try{
00411 this->qnode.execute_sequence(this->seq);
00412 }catch(std::string &error){
00413 QMessageBox msgBox;
00414 msgBox.setText(error.c_str());
00415 msgBox.setIcon(QMessageBox::Warning);
00416 msgBox.exec();
00417 }
00418 }
00419
00420 void MainWindow::on_add_step_clicked()
00421 {
00422 TMotionStep step;
00423 unsigned int i;
00424 QString value;
00425
00426 step.delay=this->ui.delay->text().toInt();
00427 step.position.resize(this->dof);
00428 step.velocity.resize(this->dof);
00429 for(i=0;i<this->dof;i++)
00430 {
00431 step.position[i]=this->desired_pos[i]->value();
00432 step.velocity[i]=this->desired_vel[i]->value();
00433 }
00434 this->seq.push_back(step);
00435 this->add_motion_step(step.position,step.velocity,step.delay);
00436 this->ui.motion_steps->selectRow(this->seq.size()-1);
00437 }
00438
00439 void MainWindow::on_delete_step_clicked()
00440 {
00441 std::vector<TMotionStep> sequence;
00442 unsigned int row,i;
00443 TMotionStep step;
00444
00445 row=this->ui.motion_steps->currentRow();
00446 if(row==(unsigned int)-1)
00447 {
00448 QMessageBox msgBox;
00449 msgBox.setText("No motion step selected.");
00450 msgBox.setIcon(QMessageBox::Warning);
00451 msgBox.exec();
00452 }
00453 else
00454 {
00455 sequence=this->seq;
00456 this->seq.clear();
00457 for(i=0;i<sequence.size();i++)
00458 {
00459 if(i!=row)
00460 this->seq.push_back(sequence[i]);
00461 }
00462 this->fill_motion_table();
00463 if(row==this->seq.size())
00464 this->ui.motion_steps->selectRow(this->seq.size()-1);
00465 else
00466 this->ui.motion_steps->selectRow(row);
00467 }
00468 }
00469
00470 void MainWindow::on_insert_step_clicked()
00471 {
00472 std::vector<TMotionStep> sequence;
00473 unsigned int row,i;
00474 TMotionStep step;
00475
00476 row=this->ui.motion_steps->currentRow();
00477 if(row==(unsigned int)-1)
00478 this->ui.add_step->click();
00479 else
00480 {
00481 step.delay=this->ui.delay->text().toInt();
00482 step.position.resize(this->dof);
00483 step.velocity.resize(this->dof);
00484 for(i=0;i<this->dof;i++)
00485 {
00486 step.position[i]=this->desired_pos[i]->value();
00487 step.velocity[i]=this->desired_vel[i]->value();
00488 }
00489 sequence=this->seq;
00490 this->seq.clear();
00491 for(i=0;i<sequence.size();i++)
00492 {
00493 if(i==row)
00494 this->seq.push_back(step);
00495 this->seq.push_back(sequence[i]);
00496 }
00497 this->fill_motion_table();
00498 this->ui.motion_steps->selectRow(row);
00499 }
00500 }
00501
00502 void MainWindow::on_motion_step_changed()
00503 {
00504 this->current_step=this->ui.motion_steps->currentRow();
00505 }
00506
00507
00508
00509
00510
00511 void MainWindow::on_actionAbout_triggered()
00512 {
00513 QMessageBox::about(this, tr("About ..."),tr("<h2>PACKAGE_NAME Test Program 0.10</h2><p>Copyright Yujin Robot</p><p>This package needs an about description.</p>"));
00514 }
00515
00516
00517
00518
00519
00520 void MainWindow::closeEvent(QCloseEvent *event)
00521 {
00522 QMainWindow::closeEvent(event);
00523 }
00524
00525 }
00526