00001
00022 #include "uga_tum_ardrone_gui.h"
00023 #include "RosThread.h"
00024 #include "PingThread.h"
00025 #include "time.h"
00026 #include "../HelperFunctions.h"
00027
00028 #include "ros/ros.h"
00029 #include "ros/package.h"
00030
00031 #include <sys/types.h>
00032 #include <dirent.h>
00033 #include <errno.h>
00034 #include <vector>
00035 #include <string>
00036 #include <iostream>
00037 #include <fstream>
00038
00039 int getdirtxt (std::string dir, std::vector<std::string> &files)
00040 {
00041 DIR *dp;
00042 struct dirent *dirp;
00043 if((dp = opendir(dir.c_str())) == NULL) {
00044 std::cout << "Error(" << errno << ") opening " << dir << std::endl;
00045 return errno;
00046 }
00047
00048 while ((dirp = readdir(dp)) != NULL) {
00049 std::string f = dirp->d_name;
00050 if(f.size() > 4 && f.substr(f.size()-4) == ".txt")
00051 files.push_back(std::string(dirp->d_name));
00052 }
00053 closedir(dp);
00054 return 0;
00055 }
00056
00057
00058 uga_tum_ardrone_gui::uga_tum_ardrone_gui(QWidget *parent)
00059 : QWidget(parent)
00060 {
00061 ui.setupUi(this);
00062 rosThread = NULL;
00063 sensGaz = sensYaw = sensRP = 1;
00064 currentControlSource = CONTROL_NONE;
00065 useHovering = true;
00066
00067 for(int i=0;i<8;i++)
00068 {
00069 isPressed[i] = false;
00070 lastRepeat[i] = 0;
00071 }
00072
00073
00074 QObject::connect( this, SIGNAL( setCountsSignal(unsigned int,unsigned int,unsigned int,unsigned int) ),
00075 this, SLOT( setCountsSlot(unsigned int,unsigned int,unsigned int,unsigned int) ) );
00076
00077 QObject::connect( this, SIGNAL( setPingsSignal(int, int) ),
00078 this, SLOT( setPingsSlot(int, int) ) );
00079
00080 QObject::connect( this, SIGNAL( setControlSourceSignal(int) ),
00081 this, SLOT( setControlSourceSlot(int) ) );
00082
00083 QObject::connect( this, SIGNAL( addLogLineSignal(QString) ),
00084 this, SLOT( addLogLineSlot(QString) ) );
00085
00086 QObject::connect( this, SIGNAL( setAutopilotInfoSignal(QString) ),
00087 this, SLOT( setAutopilotInfoSlot(QString) ) );
00088
00089 QObject::connect( this, SIGNAL( setStateestimationInfoSignal(QString) ),
00090 this, SLOT( setStateestimationInfoSlot(QString) ) );
00091
00092 QObject::connect( this, SIGNAL( setMotorSpeedsSignal(QString) ),
00093 this, SLOT( setMotorSpeedsSlot(QString) ) );
00094
00095 QObject::connect( this, SIGNAL( closeWindowSignal() ),
00096 this, SLOT( closeWindowSlot() ) );
00097
00098
00099 std::vector<std::string> files = std::vector<std::string>();
00100 getdirtxt( ros::package::getPath("uga_tum_ardrone") + std::string("/flightPlans/"),files);
00101
00102 ui.comboBoxLoadFile->addItem(QString(""), QVariant());
00103 for(unsigned int i=0;i<files.size();i++)
00104 ui.comboBoxLoadFile->addItem(QString(files[i].c_str()), QVariant());
00105
00106 }
00107
00108
00109
00110 uga_tum_ardrone_gui::~uga_tum_ardrone_gui()
00111 {
00112 }
00113
00114
00115 void uga_tum_ardrone_gui::LandClicked()
00116 {
00117 rosThread->publishCommand("c clearCommands");
00118 rosThread->sendLand();
00119 }
00120 void uga_tum_ardrone_gui::TakeoffClicked()
00121 {
00122 rosThread->sendTakeoff();
00123 }
00124 void uga_tum_ardrone_gui::ToggleCamClicked()
00125 {
00126 rosThread->sendToggleCam();
00127 }
00128 void uga_tum_ardrone_gui::FlatTrimClicked()
00129 {
00130 rosThread->sendFlattrim();
00131 }
00132 void uga_tum_ardrone_gui::EmergencyClicked()
00133 {
00134 rosThread->sendToggleState();
00135 }
00136
00137 void uga_tum_ardrone_gui::ClearClicked()
00138 {
00139 rosThread->publishCommand("c clearCommands");
00140 }
00141 void uga_tum_ardrone_gui::SendClicked()
00142 {
00143 QStringList l = ui.plainTextEditSendCommand->toPlainText().split('\n');
00144 for(int i=0;i<l.length();i++)
00145 {
00146 std::string s = l[i].trimmed().toStdString();
00147
00148 if(s.size() > 0)
00149 rosThread->publishCommand(std::string("c ")+s);
00150 }
00151 setControlSource(CONTROL_AUTO);
00152 }
00153 void uga_tum_ardrone_gui::ClearSendClicked()
00154 {
00155 ClearClicked();
00156 SendClicked();
00157 }
00158 void uga_tum_ardrone_gui::ResetClicked()
00159 {
00160 setControlSource(CONTROL_NONE);
00161 ClearClicked();
00162 rosThread->publishCommand("f reset");
00163 }
00164
00165
00166 void uga_tum_ardrone_gui::LoadFileChanged(QString val)
00167 {
00168 if(val == "")
00169 ui.plainTextEditSendCommand->setPlainText("");
00170 else
00171 {
00172 std::string path = ros::package::getPath("uga_tum_ardrone") + std::string("/flightPlans/") + val.toStdString();
00173 addLogLine("Load File "+ path);
00174
00175 std::ifstream t;
00176 t.open(path.c_str());
00177 std::string buffer = "";
00178 std::string line;
00179 while(!t.eof())
00180 {
00181 std::getline(t, line);
00182 buffer = buffer + line + "\n";
00183 }
00184 t.close();
00185
00186 ui.plainTextEditSendCommand->setPlainText(buffer.c_str());
00187 }
00188 }
00189 void uga_tum_ardrone_gui::ToggledUseHovering(int val)
00190 {
00191 useHovering = (val != 0);
00192 }
00193
00194 void uga_tum_ardrone_gui::ToggledPingDrone(int val)
00195 {
00196 pingThread->measure = (val != 0);
00197 }
00198
00199
00200 void uga_tum_ardrone_gui::ControlSourceChanged()
00201 {
00202 ControlSource s = CONTROL_NONE;
00203
00204 if(ui.radioButtonControKB->isChecked())
00205 s = CONTROL_KB;
00206 if(ui.radioButtonControlNone->isChecked())
00207 s = CONTROL_NONE;
00208 if(ui.radioButtonControlJoy->isChecked())
00209 s = CONTROL_JOY;
00210 if(ui.radioButtonControlAuto->isChecked())
00211 s = CONTROL_AUTO;
00212
00213 if(s != CONTROL_AUTO)
00214 rosThread->publishCommand("c stop");
00215 else
00216 rosThread->publishCommand("c start");
00217
00218 currentControlSource = s;
00219 }
00220
00221
00222 void uga_tum_ardrone_gui::setControlSourceSlot(int cont)
00223 {
00224
00225 currentControlSource = (ControlSource)cont;
00226 if(cont == CONTROL_KB)
00227 ui.radioButtonControKB->setChecked(true);
00228 if(cont == CONTROL_NONE)
00229 ui.radioButtonControlNone->setChecked(true);
00230 if(cont == CONTROL_JOY)
00231 ui.radioButtonControlJoy->setChecked(true);
00232 if(cont == CONTROL_AUTO)
00233 ui.radioButtonControlAuto->setChecked(true);
00234
00235 ControlSourceChanged();
00236 }
00237
00238 void uga_tum_ardrone_gui::setCountsSlot(unsigned int nav,unsigned int control,unsigned int pose,unsigned int joy)
00239 {
00240 char buf[100];
00241 snprintf(buf,100, "Drone Control: %d Hz", control);
00242 ui.labelControl->setText(buf);
00243
00244 snprintf(buf,100, "Joy Input: %d Hz", joy);
00245 ui.labelJoy->setText(buf);
00246
00247 snprintf(buf,100, "Drone Navdata: %d Hz", nav);
00248 ui.labelNavdata->setText(buf);
00249
00250 snprintf(buf,100, "Pose Estimates: %d Hz", pose);
00251 ui.labelPoseEst->setText(buf);
00252 }
00253
00254 void uga_tum_ardrone_gui::setPingsSlot(int p500, int p20000)
00255 {
00256 char buf[100];
00257 snprintf(buf,100, "Pings (RTT): %d (500B), %d (20kB)", p500, p20000);
00258 ui.labelDronePings->setText(buf);
00259 }
00260
00261 void uga_tum_ardrone_gui::addLogLineSlot(QString s)
00262 {
00263 ui.plainTextEditMessages->appendPlainText(s);
00264 }
00265 void uga_tum_ardrone_gui::setAutopilotInfoSlot(QString s)
00266 {
00267 ui.plainTextEditAutopilotStatus->setPlainText(s);
00268 }
00269 void uga_tum_ardrone_gui::setStateestimationInfoSlot(QString s)
00270 {
00271 ui.plainTextEditStateestimationStatus->setPlainText(s);
00272 }
00273 void uga_tum_ardrone_gui::setMotorSpeedsSlot(QString s)
00274 {
00275 ui.labelDroneMotors->setText(s);
00276 }
00277 void uga_tum_ardrone_gui::closeWindowSlot()
00278 {
00279 closeWindow();
00280 }
00281
00282
00283
00284
00285 void uga_tum_ardrone_gui::setCounts(unsigned int nav,unsigned int control,unsigned int pose,unsigned int joy)
00286 {
00287 emit setCountsSignal(nav, control, pose, joy);
00288 }
00289 void uga_tum_ardrone_gui::setControlSource(ControlSource cont)
00290 {
00291 emit setControlSourceSignal((int)cont);
00292 }
00293 void uga_tum_ardrone_gui::addLogLine(std::string s)
00294 {
00295 emit addLogLineSignal(QString(s.c_str()));
00296 }
00297 void uga_tum_ardrone_gui::setAutopilotInfo(std::string s)
00298 {
00299 emit setAutopilotInfoSignal(QString(s.c_str()));
00300 }
00301 void uga_tum_ardrone_gui::setMotorSpeeds(std::string s)
00302 {
00303 emit setMotorSpeedsSignal(QString(s.c_str()));
00304 }
00305 void uga_tum_ardrone_gui::setStateestimationInfo(std::string s)
00306 {
00307 emit setStateestimationInfoSignal(QString(s.c_str()));
00308 }
00309 void uga_tum_ardrone_gui::setPings(int p500, int p20000)
00310 {
00311 emit setPingsSignal(p500, p20000);
00312 }
00313 void uga_tum_ardrone_gui::closeWindow()
00314 {
00315 emit closeWindowSignal();
00316 }
00317
00318
00319
00320 int uga_tum_ardrone_gui::mapKey(int k)
00321 {
00322 switch(k)
00323 {
00324 case 74:
00325 return 0;
00326 case 75:
00327 return 1;
00328 case 76:
00329 return 2;
00330 case 73:
00331 return 3;
00332 case 85:
00333 return 4;
00334 case 79:
00335 return 5;
00336 case 81:
00337 return 6;
00338 case 65:
00339 return 7;
00340 }
00341 return -1;
00342 }
00343
00344 void uga_tum_ardrone_gui::keyReleaseEvent( QKeyEvent * key)
00345 {
00346 if(currentControlSource == CONTROL_KB)
00347 {
00348 int idx = mapKey(key->key());
00349 if(idx >= 0)
00350 {
00351 bool changed = false;
00352 if(!key->isAutoRepeat())
00353 {
00354 changed = isPressed[idx];
00355 isPressed[idx] = false;
00356 }
00357
00358 if(changed)
00359 rosThread->sendControlToDrone(calcKBControl());
00360 }
00361 }
00362 }
00363
00364 void uga_tum_ardrone_gui::keyPressEvent( QKeyEvent * key)
00365 {
00366
00367 if(currentControlSource == CONTROL_KB)
00368 {
00369 int idx = mapKey(key->key());
00370 if(idx >= 0)
00371 {
00372 bool changed = !isPressed[idx];
00373
00374 isPressed[idx] = true;
00375 lastRepeat[idx] = getMS();
00376
00377 if(changed)
00378 rosThread->sendControlToDrone(calcKBControl());
00379 }
00380
00381 else if(key->key() == 83)
00382 rosThread->sendTakeoff();
00383
00384 else if(key->key() == 68)
00385 rosThread->sendLand();
00386 }
00387
00388
00389 if(key->key() == 16777216)
00390 {
00391 setFocus();
00392 setControlSource(CONTROL_KB);
00393 }
00394
00395
00396 if(key->key() == 16777264)
00397 {
00398 rosThread->sendToggleState();
00399 }
00400 }
00401
00402 ControlCommand uga_tum_ardrone_gui::calcKBControl()
00403 {
00404
00405 for(int i=0;i<8;i++)
00406 isPressed[i] = isPressed[i] && ((lastRepeat[i] + 1000) > getMS());
00407
00408 ControlCommand c;
00409
00410 if(isPressed[0]) c.roll = -sensRP;
00411 if(isPressed[1]) c.pitch = sensRP;
00412 if(isPressed[2]) c.roll = sensRP;
00413 if(isPressed[3]) c.pitch = -sensRP;
00414 if(isPressed[4]) c.yaw = -sensYaw;
00415 if(isPressed[5]) c.yaw = sensYaw;
00416 if(isPressed[6]) c.gaz = sensGaz;
00417 if(isPressed[7]) c.gaz = -sensGaz;
00418
00419 return c;
00420 }
00421
00422
00423 void uga_tum_ardrone_gui::dynConfCb(uga_tum_ardrone::GUIParamsConfig &config, uint32_t level)
00424 {
00425 pingThread->setIp(config.DroneIP);
00426 sensRP = config.KBsensRP;
00427 sensYaw = config.KBsensYaw;
00428 sensGaz = config.KBsensGAZ;
00429 }