SlugsHilSim.cc 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Configuration Window for Slugs' HIL Simulator
 *   @author Mariano Lizarraga <malife@gmail.com>
 */


31 32
#include "SlugsHilSim.h"
#include "ui_SlugsHilSim.h"
33
#include "LinkManager.h"
34

Alejandro's avatar
Alejandro committed
35 36 37 38
#include "SlugsMAV.h"
#include "qbytearray.h"
#include "qhostaddress.h"

39 40 41 42 43
SlugsHilSim::SlugsHilSim(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SlugsHilSim)
{
    ui->setupUi(this);
44

45 46 47
    rxSocket = new QUdpSocket(this);
    txSocket = new QUdpSocket(this);

48 49
    hilLink = NULL;

50
    connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addToCombo(LinkInterface*)));
51
    connect(ui->cb_mavlinkLinks, SIGNAL(currentIndexChanged(int)), this, SLOT(linkSelected(int)));
52 53 54 55
    connect(ui->bt_startHil, SIGNAL(clicked()), this, SLOT(putInHilMode()));
    connect(rxSocket, SIGNAL(readyRead()), this, SLOT(readDatagram()));

    linksAvailable.clear();
Alejandro's avatar
Alejandro committed
56 57 58 59 60 61 62

    memset(&tmpAirData, 0, sizeof(mavlink_air_data_t));
    memset(&tmpAttitudeData, 0, sizeof(mavlink_attitude_t));
    memset(&tmpGpsData, 0, sizeof(mavlink_gps_raw_t));
    memset(&tmpGpsTime, 0, sizeof(mavlink_gps_date_time_t));
    memset(&tmpLocalPositionData, 0, sizeof(mavlink_sensor_bias_t));
    memset(&tmpRawImuData, 0, sizeof(mavlink_raw_imu_t));
Alejandro's avatar
Alejandro committed
63 64 65 66 67

    foreach (LinkInterface* link, LinkManager::instance()->getLinks())
    {
        addToCombo(link);
    }
68 69 70 71
}

SlugsHilSim::~SlugsHilSim()
{
72
    rxSocket->disconnectFromHost();
73 74
    delete ui;
}
75

76 77 78 79
void SlugsHilSim::addToCombo(LinkInterface* theLink){

  ui->cb_mavlinkLinks->addItem(theLink->getName());
  linksAvailable.insert(ui->cb_mavlinkLinks->count(),theLink);
80 81 82 83 84

  if (hilLink == NULL){
    hilLink = theLink;
  }

85
}
86

87
void SlugsHilSim::putInHilMode(void){
88

89 90 91 92 93 94 95 96 97 98 99
  bool sw_enableControls = !(ui->bt_startHil->isChecked());
  QString  buttonCaption= ui->bt_startHil->isChecked()? "Stop Slugs HIL Mode": "Set Slugs in HIL Mode";

  if (ui->bt_startHil->isChecked()){
    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText("You are about to put SLUGS in HIL Mode.");
    msgBox.setInformativeText("It will stop reading the actual sensor readings. Do you wish to continue?");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::No);

100
    if(msgBox.exec() == QMessageBox::Yes) {
101
      rxSocket->disconnectFromHost();
102
      rxSocket->bind(QHostAddress::Any, ui->ed_rxPort->text().toInt());
103
      //txSocket->bind(QHostAddress::Broadcast, ui->ed_txPort->text().toInt());
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

      ui->ed_ipAdress->setEnabled(sw_enableControls);
      ui->ed_rxPort->setEnabled(sw_enableControls);
      ui->ed_txPort->setEnabled(sw_enableControls);
      ui->cb_mavlinkLinks->setEnabled(sw_enableControls);

      ui->bt_startHil->setText(buttonCaption);

    } else {
      ui->bt_startHil->setChecked(false);
    }
  } else {
    ui->ed_ipAdress->setEnabled(sw_enableControls);
    ui->ed_rxPort->setEnabled(sw_enableControls);
    ui->ed_txPort->setEnabled(sw_enableControls);
    ui->cb_mavlinkLinks->setEnabled(sw_enableControls);

    ui->bt_startHil->setText(buttonCaption);
122 123

    rxSocket->disconnectFromHost();
124
  }
125
}
126

127 128 129 130 131 132 133 134 135 136 137 138 139
void SlugsHilSim::readDatagram(void){
  static int count = 0;
  while (rxSocket->hasPendingDatagrams()) {
           QByteArray datagram;
           datagram.resize(rxSocket->pendingDatagramSize());
           QHostAddress sender;
           quint16 senderPort;

           rxSocket->readDatagram(datagram.data(), datagram.size(),
                                   &sender, &senderPort);

           if (datagram.size() == 113) {
             processHilDatagram(&datagram);
Alejandro's avatar
Alejandro committed
140 141 142

             sendMessageToSlugs();

Alejandro's avatar
Alejandro committed
143
             commandDatagramToSimulink();
144 145 146 147 148
           }

           ui->ed_count->setText(QString::number(count++));
       }
}
149 150


151
void SlugsHilSim::activeUasSet(UASInterface* uas){
152

153 154 155
  if (uas != NULL) {
    activeUas = static_cast <UAS *>(uas);
  }
156 157 158
}


pixhawk's avatar
pixhawk committed
159 160 161
void SlugsHilSim::processHilDatagram(const QByteArray* datagram)
{
    #ifdef MAVLINK_ENABLED_SLUGS
162 163 164 165 166 167 168 169 170 171 172
  unsigned char i = 0;

  mavlink_message_t msg;

  tmpGpsTime.year  = datagram->at(i++);
  tmpGpsTime.month = datagram->at(i++);
  tmpGpsTime.day   = datagram->at(i++);
  tmpGpsTime.hour  = datagram->at(i++);
  tmpGpsTime.min   = datagram->at(i++);
  tmpGpsTime.sec   = datagram->at(i++);

Alejandro's avatar
Alejandro committed
173 174 175
  tmpGpsData.lat = getFloatFromDatagram(datagram, &i);
  tmpGpsData.lon = getFloatFromDatagram(datagram, &i);
  tmpGpsData.alt = getFloatFromDatagram(datagram, &i);
176

Alejandro's avatar
Alejandro committed
177 178
  tmpGpsData.hdg = getUint16FromDatagram(datagram, &i);
  tmpGpsData.v   = getUint16FromDatagram(datagram, &i);
179

Alejandro's avatar
Alejandro committed
180 181
  tmpGpsData.eph = getUint16FromDatagram(datagram, &i);
  tmpGpsData.fix_type = datagram->at(i++);
182
  tmpGpsTime.visSat  = datagram->at(i++);
Alejandro's avatar
Alejandro committed
183
  i++;
184

Alejandro's avatar
Alejandro committed
185 186 187
  tmpAirData.dynamicPressure= getFloatFromDatagram(datagram, &i);
  tmpAirData.staticPressure= getFloatFromDatagram(datagram, &i);
  tmpAirData.temperature= getUint16FromDatagram(datagram, &i);
188

Alejandro's avatar
Alejandro committed
189 190
  // TODO Salto en el Datagrama
  i=i+8;
191

Alejandro's avatar
Alejandro committed
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
  tmpRawImuData.xgyro = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.ygyro = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.zgyro = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.xacc = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.yacc = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.zacc = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.xmag = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.ymag = getUint16FromDatagram(datagram, &i);
  tmpRawImuData.zmag = getUint16FromDatagram(datagram, &i);

  tmpAttitudeData.roll = getFloatFromDatagram(datagram, &i);
  tmpAttitudeData.pitch = getFloatFromDatagram(datagram, &i);
  tmpAttitudeData.yaw = getFloatFromDatagram(datagram, &i);

  tmpAttitudeData.rollspeed = getFloatFromDatagram(datagram, &i);
  tmpAttitudeData.pitchspeed = getFloatFromDatagram(datagram, &i);
  tmpAttitudeData.yawspeed = getFloatFromDatagram(datagram, &i);
209

Alejandro's avatar
Alejandro committed
210 211
  // TODO Crear Paquete SYNC TIME
  i=i+2;
212

Alejandro's avatar
Alejandro committed
213 214 215 216 217 218
  tmpLocalPositionData.x = getFloatFromDatagram(datagram, &i);
  tmpLocalPositionData.y = getFloatFromDatagram(datagram, &i);
  tmpLocalPositionData.z = getFloatFromDatagram(datagram, &i);
  tmpLocalPositionData.vx = getFloatFromDatagram(datagram, &i);
  tmpLocalPositionData.vy = getFloatFromDatagram(datagram, &i);
  tmpLocalPositionData.vz = getFloatFromDatagram(datagram, &i);
219

220

Alejandro's avatar
Alejandro committed
221 222
//  mavlink_msg_gps_date_time_encode(MG::SYSTEM::ID,MG::SYSTEM::COMPID, &msg, &tmpGpsTime);
//  activeUas->sendMessage(hilLink, msg);
223

Alejandro's avatar
Alejandro committed
224 225 226 227
//  memset(&msg, 0, sizeof(mavlink_message_t));

//  mavlink_msg_gps_raw_encode(MG::SYSTEM::ID,MG::SYSTEM::COMPID, &msg, &tmpGpsRaw);
//  activeUas->sendMessage(hilLink,msg);
228 229 230 231

  // TODO: this is legacy of old HIL datagram. Need to remove from Simulink model
  i++;

Alejandro's avatar
Alejandro committed
232 233 234 235 236 237 238 239
  ui->ed_1->setText(QString::number(tmpRawImuData.xacc));
  ui->ed_2->setText(QString::number(tmpRawImuData.yacc));
  ui->ed_3->setText(QString::number(tmpRawImuData.zacc));

  ui->tbA->setText(QString::number(tmpRawImuData.xgyro));
  ui->tbB->setText(QString::number(tmpRawImuData.ygyro));
  ui->tbC->setText(QString::number(tmpRawImuData.zgyro));

pixhawk's avatar
pixhawk committed
240 241 242
#else
  Q_UNUSED(datagram);
#endif
243 244
}

245 246
float SlugsHilSim::getFloatFromDatagram (const QByteArray* datagram, unsigned char * i){
  tFloatToChar tmpF2C;
247

248 249 250 251
  tmpF2C.chData[0] = datagram->at((*i)++);
  tmpF2C.chData[1] = datagram->at((*i)++);
  tmpF2C.chData[2] = datagram->at((*i)++);
  tmpF2C.chData[3] = datagram->at((*i)++);
252

253 254 255 256 257 258 259 260 261 262
  return tmpF2C.flData;
}

uint16_t SlugsHilSim::getUint16FromDatagram (const QByteArray* datagram, unsigned char * i){
  tUint16ToChar tmpU2C;

  tmpU2C.chData[0] = datagram->at((*i)++);
  tmpU2C.chData[1] = datagram->at((*i)++);

  return tmpU2C.uiData;
263

264
}
265 266

void SlugsHilSim::linkSelected(int cbIndex){
267 268
  #ifdef MAVLINK_ENABLED_SLUGS
    // HIL code to go here...
269
  //hilLink = linksAvailable
pixhawk's avatar
pixhawk committed
270
    // FIXME Mariano
Alejandro's avatar
Alejandro committed
271 272

    hilLink = LinkManager::instance()->getLinkForId(cbIndex);
273
}
Alejandro's avatar
Alejandro committed
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

void SlugsHilSim::sendMessageToSlugs()
{
    mavlink_message_t msg;

    mavlink_msg_local_position_encode(MG::SYSTEM::ID,
                                     MG::SYSTEM::COMPID,
                                    &msg,
                                    &tmpLocalPositionData);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));

    mavlink_msg_attitude_encode(MG::SYSTEM::ID,
                               MG::SYSTEM::COMPID,
                              &msg,
                              &tmpAttitudeData);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));

    mavlink_msg_raw_imu_encode(MG::SYSTEM::ID,
                                     MG::SYSTEM::COMPID,
                                    &msg,
                                    &tmpRawImuData);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));

    mavlink_msg_air_data_encode(MG::SYSTEM::ID,
                               MG::SYSTEM::COMPID,
                              &msg,
                              &tmpAirData);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));

    mavlink_msg_gps_raw_encode(MG::SYSTEM::ID,
                               MG::SYSTEM::COMPID,
                              &msg,
                              &tmpGpsData);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));

    mavlink_msg_gps_date_time_encode(MG::SYSTEM::ID,
                                     MG::SYSTEM::COMPID,
                                    &msg,
                                    &tmpGpsTime);
    activeUas->sendMessage(hilLink, msg);
    memset(&msg, 0, sizeof(mavlink_message_t));
}


Alejandro's avatar
Alejandro committed
323
void SlugsHilSim::commandDatagramToSimulink()
Alejandro's avatar
Alejandro committed
324 325 326
{
    //mavlink_pwm_commands_t* pwdC = (static_cast<SlugsMAV*>(activeUas))->getPwmCommands();

Alejandro's avatar
Alejandro committed
327 328 329 330
    mavlink_pwm_commands_t* pwdC;

    if(pwdC != NULL){
    }
Alejandro's avatar
Alejandro committed
331

Alejandro's avatar
Alejandro committed
332 333 334 335
    QByteArray data;
    data.resize(22);

    unsigned char i=0;
Alejandro's avatar
Alejandro committed
336 337 338 339 340 341 342 343 344 345 346
    setUInt16ToDatagram(data, &i, 1);//pwdC->dt_c);
    setUInt16ToDatagram(data, &i, 2);//pwdC->dla_c);
    setUInt16ToDatagram(data, &i, 3);//pwdC->dra_c);
    setUInt16ToDatagram(data, &i, 4);//pwdC->dr_c);
    setUInt16ToDatagram(data, &i, 5);//pwdC->dle_c);
    setUInt16ToDatagram(data, &i, 6);//pwdC->dre_c);
    setUInt16ToDatagram(data, &i, 7);//pwdC->dlf_c);
    setUInt16ToDatagram(data, &i, 8);//pwdC->drf_c);
    setUInt16ToDatagram(data, &i, 9);//pwdC->aux1);
    setUInt16ToDatagram(data, &i, 10);//pwdC->aux2);
    setUInt16ToDatagram(data, &i, 11);//value default
Alejandro's avatar
Alejandro committed
347 348 349 350 351 352 353 354 355 356 357

    txSocket->writeDatagram(data, QHostAddress::Broadcast, ui->ed_txPort->text().toInt());
}

void SlugsHilSim::setUInt16ToDatagram(QByteArray& datagram, unsigned char* pos, uint16_t value)
{
    tUint16ToChar tmpUnion;
    tmpUnion.uiData= value;

    datagram[(*pos)++]= tmpUnion.chData[0];
    datagram[(*pos)++]= tmpUnion.chData[1];
358
}