Commit ba258011 authored by Cyrill Burgener's avatar Cyrill Burgener
Browse files

merged roangel's branch into pps_project

parents fb2ad4b3 cc1fc535
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.0.2, 2017-05-24T18:06:39. -->
<!-- Written by QtCreator 4.0.2, 2017-05-26T12:05:49. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
......
......@@ -20,19 +20,26 @@ public:
int student_id;
int cf_zone_index;
std::string cf_name;
std::string radio_address;;
};
explicit CFLinker(Ui::MainGUIWindow* ui, std::vector<crazyFly*> *crazyflies_vector, std::vector<crazyFlyZone*> *crazyfly_zones);
~CFLinker();
void link();
void unlink();
void link(int student_id, int cf_zone_index, std::string cf_name, std::string radio_address);
void unlink_selection();
void unlink_cf_zone(int cf_zone_index);
std::vector<struct link> links;
bool isStudentIDLinked(int student_id);
bool isCFZoneLinked(int cf_zone_index);
bool isCFLinked(std::string cf_name);
bool isRadioAddressLinked(std::string radio_address);
int getCFZoneIndexFromName(QString name);
int getCFIndexFromName(std::string name);
void clear_all_links();
signals:
void updateComboBoxes();
......@@ -45,9 +52,7 @@ private:
std::vector<crazyFly*>* m_crazyflies_vector;
std::vector<crazyFlyZone*>* m_crazyfly_zones;
int getCFZoneIndexFromName(QString name);
int getCFIndexFromName(std::string name);
void addNewRow(int student_id, std::string crazyfly_name, int cf_zone_index);
void addNewRow(int student_id, std::string crazyfly_name, int cf_zone_index, std::string radio_address);
};
......
......@@ -13,6 +13,12 @@
#include "marker.h"
#include "crazyFly.h"
#include "CFLinker.h"
#include "d_fall_pps/CrazyflieDB.h"
#include "d_fall_pps/CrazyflieEntry.h"
using namespace d_fall_pps;
#endif
......@@ -99,6 +105,10 @@ private slots:
void on_checkBox_vicon_highlight_markers_toggled(bool checked);
void on_save_in_DB_button_clicked();
void on_load_from_DB_button_clicked();
#ifdef CATKIN_MAKE
void updateNewViconData(const ptrToMessage& p_msg);
#endif
......@@ -115,6 +125,9 @@ private slots:
void updateComboBoxes();
void setTabIndex(int index);
void doTabClosed(int tab_index);
private:
Ui::MainGUIWindow *ui;
......@@ -133,6 +146,20 @@ private:
void updateComboBoxesCFZones();
int getTabIndexFromName(QString name);
CrazyflieDB m_data_base;
void clear_database_file();
void fill_database_file();
int read_database_from_file(CrazyflieDB &read_db);
void save_database_file();
void insert_or_update_entry_database(CrazyflieEntry entry);
};
......
......@@ -44,8 +44,12 @@ public:
void removeTable();
void addCFZone(QRectF rect, int index);
void removeAllCFZones();
public slots:
void removeCrazyFlyZone(int index);
void removeCrazyFlyZone(int cf_zone_index);
void setSelectedCrazyFlyZone(int index);
void changeModeTo(int next_mode);
......@@ -72,7 +76,6 @@ private:
void addCrazyFlyZoneToVector(crazyFlyZone* rect);
void addTablePieceToVector(tablePiece* rect);
int checkSelectedCrazyFlyZone();
void updateIndexesAndLabelsCrazyFlyZones();
void removeTablePiece(int index);
QPen* pen;
......
......@@ -33,6 +33,10 @@ public:
// void messageCallback(const ViconData& data);
void messageCallback(const ptrToMessage& p_msg);
ros::ServiceClient m_read_db_client;
ros::ServiceClient m_update_db_client;
ros::ServiceClient m_command_db_client;
signals:
......
......@@ -44,6 +44,19 @@ bool CFLinker::isStudentIDLinked(int student_id)
return is_linked;
}
bool CFLinker::isRadioAddressLinked(std::string radio_address)
{
bool is_linked = false;
for(int i = 0; i < links.size(); i++)
{
if(links[i].radio_address == radio_address)
{
is_linked = true;
}
}
return is_linked;
}
bool CFLinker::isCFZoneLinked(int cf_zone_index)
{
bool is_linked = false;
......@@ -72,7 +85,7 @@ bool CFLinker::isCFLinked(std::string cf_name)
}
void CFLinker::addNewRow(int student_id, std::string crazyfly_name, int cf_zone_index)
void CFLinker::addNewRow(int student_id, std::string crazyfly_name, int cf_zone_index, std::string radio_address)
{
m_ui->table_links->insertRow(m_ui->table_links->rowCount());
QString str_id = QString::number(student_id);
......@@ -89,24 +102,32 @@ void CFLinker::addNewRow(int student_id, std::string crazyfly_name, int cf_zone_
QTableWidgetItem *item_cf_zone = new QTableWidgetItem(str_cf_zone_index);
item_cf_zone->setFlags(item_cf_zone->flags() & ~Qt::ItemIsEditable);
m_ui->table_links->setItem(m_ui->table_links->rowCount() - 1, 2, item_cf_zone);
QString str_radio_address = QString::fromStdString(radio_address);
QTableWidgetItem *item_radio_address = new QTableWidgetItem(str_radio_address);
item_cf->setFlags(item_radio_address->flags() & ~Qt::ItemIsEditable);
m_ui->table_links->setItem(m_ui->table_links->rowCount() - 1, 3, item_radio_address);
}
void CFLinker::link()
void CFLinker::link(int student_id, int cf_zone_index, std::string cf_name, std::string radio_address)
{
m_ui->table_links->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
struct link tmp_link;
tmp_link.student_id = m_ui->spinBox_student_ids->value();
tmp_link.cf_zone_index = getCFZoneIndexFromName(m_ui->comboBoxCFZones->currentText());
tmp_link.cf_name = m_ui->comboBoxCFs->currentText().toStdString();
tmp_link.student_id = student_id;
tmp_link.cf_zone_index = cf_zone_index;
tmp_link.cf_name = cf_name;
tmp_link.radio_address = radio_address;
ROS_INFO("tmp_link.student_id %d", tmp_link.student_id);
ROS_INFO("tmp_link.cf_zone_index %d", tmp_link.cf_zone_index);
ROS_INFO("tmp_link.cf_name %s", tmp_link.cf_name.c_str());
ROS_INFO("tmp_link.radio_address %s", tmp_link.radio_address.c_str());
(*m_crazyfly_zones)[tmp_link.cf_zone_index]->linkCF(tmp_link.cf_name);
(*m_crazyflies_vector)[getCFIndexFromName(tmp_link.cf_name)]->assignCFZone(tmp_link.cf_zone_index);
// (*m_crazyfly_zones)[tmp_link.cf_zone_index]->linkCF(tmp_link.cf_name);
// (*m_crazyflies_vector)[getCFIndexFromName(tmp_link.cf_name)]->assignCFZone(tmp_link.cf_zone_index);
addNewRow(m_ui->spinBox_student_ids->value(), tmp_link.cf_name, tmp_link.cf_zone_index);
addNewRow(tmp_link.student_id, tmp_link.cf_name, tmp_link.cf_zone_index, tmp_link.radio_address);
links.push_back(tmp_link);
// TODO: remove options linked from available ones
......@@ -123,7 +144,38 @@ void CFLinker::link()
// ui->comboBox->setItemData(index, 33, Qt::UserRole - 1);
}
void CFLinker::unlink()
void CFLinker::clear_all_links()
{
links.clear();
m_ui->table_links->setRowCount(0);
emit updateComboBoxes();
}
void CFLinker::unlink_cf_zone(int cf_zone_index)
{
for(int i = 0; i < links.size(); i++)
{
if(links[i].cf_zone_index == cf_zone_index)
{
links.erase(links.begin() + i);
break;
}
}
// remove them graphically
for(int i = 0; i < m_ui->table_links->rowCount(); i++)
{
QString name = m_ui->table_links->item(i, 2)->text(); //2 because cf zone
if(getCFZoneIndexFromName(name) == cf_zone_index)
{
m_ui->table_links->removeRow(i);
break;
}
}
// update combo boxes
emit updateComboBoxes();
}
void CFLinker::unlink_selection()
{
QModelIndexList selection = m_ui->table_links->selectionModel()->selectedRows();
......
......@@ -14,6 +14,11 @@
#ifdef CATKIN_MAKE
#include "d_fall_pps/UnlabeledMarker.h"
#include "d_fall_pps/CMRead.h"
#include "d_fall_pps/CrazyflieEntry.h"
#include "d_fall_pps/CMUpdate.h"
#include "d_fall_pps/CMCommand.h"
#include "CentralManagerService.h"
#endif
#include <string>
......@@ -41,19 +46,66 @@ MainGUIWindow::~MainGUIWindow()
delete ui;
}
int MainGUIWindow::getTabIndexFromName(QString name)
{
int found_name = -1;
for(int i = 0; i < ui->tabWidget->count(); i++)
{
qDebug("name: %s", name.toStdString().c_str());
qDebug("tabText: %s", ui->tabWidget->tabText(i).toStdString().c_str());
if(name == ui->tabWidget->tabText(i))
{
found_name = i;
}
}
return found_name;
}
void MainGUIWindow::doNumCrazyFlyZonesChanged(int n)
{
// tabs number management, maybe do it in a different way so we dont have to remove and add everything?
ui->tabWidget->clear();
for (int i = 0; i < n; i++)
// first check if size of tabs is greater than size of vector or viceversa. Have we removed or added a zone?
qDebug("tabWidgetCount : %d", ui->tabWidget->count());
if(ui->tabWidget->count() > scene->crazyfly_zones.size())
{
// we removed one crazyfly_zone, n means index of the one we removed. Look for that index tab and remove it
QString qstr = "CrazyFly ";
qstr.append(QString::number(i+1));
crazyFlyZoneTab* widget = new crazyFlyZoneTab(i);
ui->tabWidget->addTab(widget, qstr);
qstr.append(QString::number(n+1));
if(scene->crazyfly_zones.size() == 0)
{
ui->tabWidget->clear();
}
int found_index = getTabIndexFromName(qstr);
if(found_index != -1)
{
ui->tabWidget->removeTab(found_index);
}
// now unlink it from table also:
#ifdef CATKIN_MAKE
if(cf_linker->isCFZoneLinked(n))
{
cf_linker->unlink_cf_zone(n);
}
#endif
}
else if(ui->tabWidget->count() < scene->crazyfly_zones.size())
{
// we added one crazyfly_zone, n means index of the new one. New tab will be labeld index + 1
QString qstr = "CrazyFly ";
qstr.append(QString::number(n+1));
crazyFlyZoneTab* widget = new crazyFlyZoneTab(n);
ui->tabWidget->insertTab(n, widget, qstr);
connect(widget, SIGNAL(centerButtonClickedSignal(int)), this, SLOT(centerViewIndex(int)));
}
// for (int i = 0; i < n; i++)
// {
// QString qstr = "CrazyFly ";
// qstr.append(QString::number(i+1));
// crazyFlyZoneTab* widget = new crazyFlyZoneTab(i);
// ui->tabWidget->addTab(widget, qstr);
// connect(widget, SIGNAL(centerButtonClickedSignal(int)), this, SLOT(centerViewIndex(int)));
// }
updateComboBoxesCFZones();
}
......@@ -81,13 +133,15 @@ void MainGUIWindow::_init()
ui->err_message_cf->setStyleSheet("QLabel { color : red; }");
ui->err_message_cf_zone->setStyleSheet("QLabel { color : red; }");
ui->err_message_student_id->setStyleSheet("QLabel { color : red; }");
ui->err_message_radio_address->setStyleSheet("QLabel { color : red; }");
ui->err_message_cf->clear();
ui->err_message_cf_zone->clear();
ui->err_message_student_id->clear();
ui->err_message_radio_address->clear();
// initialize table_links
ui->table_links->setColumnCount(3);
ui->table_links->setColumnCount(4);
QFont fnt;
fnt.setPointSize(7);
......@@ -108,7 +162,7 @@ void MainGUIWindow::_init()
}
ui->table_links->setSelectionBehavior(QAbstractItemView::SelectRows);
QStringList horizontal_header;
horizontal_header << "Student ID" << "CrazyFly" << "CrazyFly Zone";
horizontal_header << "Student ID" << "CrazyFly" << "CrazyFly Zone" << "Radio Address";
ui->table_links->setHorizontalHeaderLabels(horizontal_header);
// scene
......@@ -122,10 +176,9 @@ void MainGUIWindow::_init()
cf_linker = new CFLinker(ui, &crazyflies_vector, &scene->crazyfly_zones);
#endif
// connections
QObject::connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), scene, SLOT(removeCrazyFlyZone(int)));
QObject::connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(doTabClosed(int)));
QObject::connect(scene, SIGNAL(numCrazyFlyZonesChanged(int)), this, SLOT(doNumCrazyFlyZonesChanged(int)));
QObject::connect(ui->tabWidget, SIGNAL(currentChanged(int)), scene, SLOT(setSelectedCrazyFlyZone(int)));
QObject::connect(scene, SIGNAL(crazyFlyZoneSelected(int)), ui->tabWidget, SLOT(setCurrentIndex(int)));
QObject::connect(scene, SIGNAL(crazyFlyZoneSelected(int)), this, SLOT(setTabIndex(int)));
QObject::connect(scene, SIGNAL(modeChanged(int)), this, SLOT(transitionToMode(int)));
QObject::connect(scene, SIGNAL(numTablePiecesChanged(int)), this, SLOT(handleTablePiecesNumChanged(int)));
......@@ -139,6 +192,22 @@ void MainGUIWindow::_init()
#endif
}
void MainGUIWindow::doTabClosed(int tab_index)
{
QString name = ui->tabWidget->tabText(tab_index);
#ifdef CATKIN_MAKE
int cf_zone_index = cf_linker->getCFZoneIndexFromName(name);
scene->removeCrazyFlyZone(cf_zone_index);
#endif
}
void MainGUIWindow::setTabIndex(int index)
{
QString qstr = "CrazyFly ";
qstr.append(QString::number(index + 1));
ui->tabWidget->setCurrentIndex(getTabIndexFromName(qstr));
}
void MainGUIWindow::updateComboBoxes()
{
updateComboBoxesCFs();
......@@ -167,8 +236,9 @@ void MainGUIWindow::updateComboBoxesCFZones()
{
if(!cf_linker->isCFZoneLinked(scene->crazyfly_zones[i]->getIndex()))
{
int cf_zone_index = scene->crazyfly_zones[i]->getIndex();
QString qstr = "CrazyFlyZone ";
qstr.append(QString::number(i+1));
qstr.append(QString::number(cf_zone_index + 1));
ui->comboBoxCFZones->addItem(qstr);
}
}
......@@ -273,7 +343,7 @@ void MainGUIWindow::updateNewViconData(const ptrToMessage& p_msg) //connected to
// in this loop, clean the ones that are not present anymore. UPDATE: this will apparently only happen when we tick and untick in Vicon
int crazyfly_vector_size_after = crazyflies_vector.size();
for(int j = 0; j < crazyfly_vector_size_after; j++)
for(int j = crazyfly_vector_size_after - 1; j >= 0; j--)
{
bool name_found = false;
for(int i = 0; i < p_msg->crazyflies.size(); i++)
......@@ -421,10 +491,12 @@ void MainGUIWindow::on_checkBox_crazyfly_zones_toggled(bool checked)
void MainGUIWindow::on_tabWidget_currentChanged(int index)
{
if(index >= 0)
{
scene->setSelectedCrazyFlyZone(index);
}
// this index is tab index. Need to go to cf index
QString name = ui->tabWidget->tabText(index);
#ifdef CATKIN_MAKE
int cf_index = cf_linker->getCFZoneIndexFromName(name);
scene->setSelectedCrazyFlyZone(cf_index);
#endif
}
void MainGUIWindow::centerViewIndex(int index)
......@@ -589,6 +661,7 @@ void MainGUIWindow::on_link_button_clicked()
{
ui->err_message_cf->clear();
}
if(ui->comboBoxCFZones->count() == 0)
{
// plot error message
......@@ -600,6 +673,21 @@ void MainGUIWindow::on_link_button_clicked()
ui->err_message_cf_zone->clear();
}
if(cf_linker->isRadioAddressLinked(ui->radioAddress_text->text().toStdString()))
{
ui->err_message_radio_address->setText("Already in use");
error = true;
}
else if(ui->radioAddress_text->text().toStdString() == "")
{
ui->err_message_radio_address->setText("Field is empty");
error = true;
}
else
{
ui->err_message_radio_address->clear();
}
if(cf_linker->isStudentIDLinked(ui->spinBox_student_ids->value()))
{
// plot error message
......@@ -613,7 +701,7 @@ void MainGUIWindow::on_link_button_clicked()
if(!error)
{
cf_linker->link();
cf_linker->link(ui->spinBox_student_ids->value(), cf_linker->getCFZoneIndexFromName(ui->comboBoxCFZones->currentText()), ui->comboBoxCFs->currentText().toStdString(), ui->radioAddress_text->text().toStdString());
}
#endif
}
......@@ -621,6 +709,167 @@ void MainGUIWindow::on_link_button_clicked()
void MainGUIWindow::on_unlink_button_clicked()
{
#ifdef CATKIN_MAKE
cf_linker->unlink();
cf_linker->unlink_selection();
#endif
}
void MainGUIWindow::on_save_in_DB_button_clicked()
{
// we need to update and then save?
CrazyflieDB tmp_db;
for(int i = 0; i < cf_linker->links.size(); i++)
{
CrazyflieEntry tmp_entry;
tmp_entry.crazyflieContext.crazyflieName = cf_linker->links[i].cf_name;
tmp_entry.crazyflieContext.crazyflieAddress = cf_linker->links[i].radio_address;
tmp_entry.crazyflieContext.localArea.crazyfly_zone_index = cf_linker->links[i].cf_zone_index;
tmp_entry.studentID = cf_linker->links[i].student_id;
for(int j = 0; j < scene->crazyfly_zones.size(); j++)
{
if(cf_linker->links[i].cf_zone_index == scene->crazyfly_zones[j]->getIndex())
{
double x_min = scene->crazyfly_zones[j]->sceneBoundingRect().bottomLeft().x();
double y_min = - scene->crazyfly_zones[j]->sceneBoundingRect().bottomLeft().y();
double x_max = scene->crazyfly_zones[j]->sceneBoundingRect().topRight().x();
double y_max = -scene->crazyfly_zones[j]->sceneBoundingRect().topRight().y();
tmp_entry.crazyflieContext.localArea.xmin = x_min * FROM_UNITS_TO_METERS;
tmp_entry.crazyflieContext.localArea.xmax = x_max * FROM_UNITS_TO_METERS;
tmp_entry.crazyflieContext.localArea.ymin = y_min * FROM_UNITS_TO_METERS;
tmp_entry.crazyflieContext.localArea.ymax = y_max * FROM_UNITS_TO_METERS;
}
}
tmp_db.crazyflieEntries.push_back(tmp_entry);
}
m_data_base = tmp_db;
ROS_INFO_STREAM("database:\n" << m_data_base);
// save the database in the file
fill_database_file();
}
void MainGUIWindow::clear_database_file()
{
CrazyflieDB tmp_db;
if(read_database_from_file(tmp_db) == 0)
{
for(int i = 0; i < tmp_db.crazyflieEntries.size(); i++)
{
CMUpdate updateCall;
updateCall.request.mode = ENTRY_REMOVE;
updateCall.request.crazyflieEntry.crazyflieContext.crazyflieName = tmp_db.crazyflieEntries[i].crazyflieContext.crazyflieName;
if(_rosNodeThread->m_update_db_client.call(updateCall))
{
ROS_INFO("database changed in central manager service");
}
else
{
ROS_ERROR("Failed to remove entry in DB");
}
}
save_database_file();
}
else
{
ROS_INFO("Failed to read DB");
}
}
void MainGUIWindow::fill_database_file()
{
clear_database_file();
ROS_INFO("cleared data base file");
ROS_INFO_STREAM("database:\n" << m_data_base);
for(int i = 0; i < m_data_base.crazyflieEntries.size(); i++)
{
ROS_INFO("inserted 1 item in DB");
insert_or_update_entry_database(m_data_base.crazyflieEntries[i]);
}
save_database_file();
}
void MainGUIWindow::save_database_file()
{
CMCommand commandCall;
commandCall.request.command = CMD_SAVE;
if(_rosNodeThread->m_command_db_client.call(commandCall))
{
ROS_INFO("successfully saved db");
}
else
{
ROS_ERROR("failed to save db");
}
}
void MainGUIWindow::insert_or_update_entry_database(CrazyflieEntry entry)
{
CMUpdate updateCall;
updateCall.request.mode = ENTRY_INSERT_OR_UPDATE;
updateCall.request.crazyflieEntry = entry;
_rosNodeThread->m_update_db_client.call(updateCall);
}
int MainGUIWindow::read_database_from_file(CrazyflieDB &read_db)
{
CMRead getDBCall;
_rosNodeThread->m_read_db_client.waitForExistence(ros::Duration(-1));
if(_rosNodeThread->m_read_db_client.call(getDBCall))
{
read_db = getDBCall.response.crazyflieDB;
return 0;
}
else
{
return -1;
<