Skip to content
MockLink.cc 35.1 KiB
Newer Older
Don Gagne's avatar
Don Gagne committed
/*=====================================================================
Don Gagne's avatar
Don Gagne committed
 QGroundControl Open Source Ground Control Station
Don Gagne's avatar
Don Gagne committed
 (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
Don Gagne's avatar
Don Gagne committed
 This file is part of the QGROUNDCONTROL project
Don Gagne's avatar
Don Gagne committed
 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.
Don Gagne's avatar
Don Gagne committed
 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.
Don Gagne's avatar
Don Gagne committed
 You should have received a copy of the GNU General Public License
 along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
Don Gagne's avatar
Don Gagne committed
 ======================================================================*/

#include "MockLink.h"
#include "QGCLoggingCategory.h"
#include "QGCApplication.h"
Don Gagne's avatar
Don Gagne committed

#include <QTimer>
#include <QDebug>
#include <QFile>

#include <string.h>

QGC_LOGGING_CATEGORY(MockLinkLog, "MockLinkLog")
Don Gagne's avatar
Don Gagne committed
QGC_LOGGING_CATEGORY(MockLinkVerboseLog, "MockLinkVerboseLog")
Don Gagne's avatar
Don Gagne committed
/// @file
///     @brief Mock implementation of a Link.
///
///     @author Don Gagne <don@thegagnes.com>

Don Gagne's avatar
Don Gagne committed
enum PX4_CUSTOM_MAIN_MODE {
    PX4_CUSTOM_MAIN_MODE_MANUAL = 1,
    PX4_CUSTOM_MAIN_MODE_ALTCTL,
    PX4_CUSTOM_MAIN_MODE_POSCTL,
    PX4_CUSTOM_MAIN_MODE_AUTO,
    PX4_CUSTOM_MAIN_MODE_ACRO,
    PX4_CUSTOM_MAIN_MODE_OFFBOARD,
    PX4_CUSTOM_MAIN_MODE_STABILIZED,
    PX4_CUSTOM_MAIN_MODE_RATTITUDE
Don Gagne's avatar
Don Gagne committed
};

enum PX4_CUSTOM_SUB_MODE_AUTO {
    PX4_CUSTOM_SUB_MODE_AUTO_READY = 1,
    PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF,
    PX4_CUSTOM_SUB_MODE_AUTO_LOITER,
    PX4_CUSTOM_SUB_MODE_AUTO_MISSION,
    PX4_CUSTOM_SUB_MODE_AUTO_RTL,
    PX4_CUSTOM_SUB_MODE_AUTO_LAND,
    PX4_CUSTOM_SUB_MODE_AUTO_RTGS
};

union px4_custom_mode {
    struct {
        uint16_t reserved;
        uint8_t main_mode;
        uint8_t sub_mode;
    };
    uint32_t data;
    float data_float;
};

Don Gagne's avatar
Don Gagne committed
float MockLink::_vehicleLatitude =  47.633033f;
float MockLink::_vehicleLongitude = -122.08794f;
Don Gagne's avatar
Don Gagne committed
float MockLink::_vehicleAltitude =  3.5f;
const char* MockConfiguration::_firmwareTypeKey =   "FirmwareType";
const char* MockConfiguration::_vehicleTypeKey =    "VehicleType";
const char* MockConfiguration::_sendStatusTextKey = "SendStatusText";
MockLink::MockLink(MockConfiguration* config)
    : _missionItemHandler(this, qgcApp()->toolbox()->mavlinkProtocol())
    , _name("MockLink")
    , _connected(false)
    , _vehicleSystemId(128)     // FIXME: Pull from eventual parameter manager
    , _vehicleComponentId(200)  // FIXME: magic number?
    , _inNSH(false)
Don Gagne's avatar
Don Gagne committed
    , _mavlinkStarted(true)
    , _mavBaseMode(MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED)
    , _mavState(MAV_STATE_STANDBY)
Don Gagne's avatar
Don Gagne committed
    , _firmwareType(MAV_AUTOPILOT_PX4)
    , _vehicleType(MAV_TYPE_QUADROTOR)
    , _fileServer(NULL)
    , _sendStatusText(false)
Don Gagne's avatar
Don Gagne committed
    , _apmSendHomePositionOnEmptyList(false)
    , _sendHomePositionDelayCount(2)
Don Gagne's avatar
Don Gagne committed
    if (_config) {
Don Gagne's avatar
Don Gagne committed
        _firmwareType = config->firmwareType();
        _vehicleType = config->vehicleType();
        _sendStatusText = config->sendStatusText();
Don Gagne's avatar
Don Gagne committed
        _config->setLink(this);
Don Gagne's avatar
Don Gagne committed
    union px4_custom_mode   px4_cm;

    px4_cm.data = 0;
    px4_cm.main_mode = PX4_CUSTOM_MAIN_MODE_MANUAL;
    _mavCustomMode = px4_cm.data;

    _fileServer = new MockLinkFileServer(_vehicleSystemId, _vehicleComponentId, this);
    Q_CHECK_PTR(_fileServer);
Don Gagne's avatar
Don Gagne committed
    moveToThread(this);
Don Gagne's avatar
Don Gagne committed
    _loadParams();
}

MockLink::~MockLink(void)
{
bool MockLink::_connect(void)
    if (!_connected) {
        _connected = true;
        start();
        emit connected();
    }
Don Gagne's avatar
Don Gagne committed
    return true;
}

Don Gagne's avatar
Don Gagne committed
void MockLink::_disconnect(void)
    if (_connected) {
        _connected = false;
Daniel Agar's avatar
Daniel Agar committed
        quit();
        wait();
        emit disconnected();
    }
Don Gagne's avatar
Don Gagne committed
}

void MockLink::run(void)
{
    QTimer  _timer1HzTasks;
    QTimer  _timer10HzTasks;
    QTimer  _timer50HzTasks;
dogmaphobic's avatar
dogmaphobic committed
    QObject::connect(&_timer1HzTasks,  &QTimer::timeout, this, &MockLink::_run1HzTasks);
Don Gagne's avatar
Don Gagne committed
    QObject::connect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
    QObject::connect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks);
Don Gagne's avatar
Don Gagne committed
    _timer1HzTasks.start(1000);
    _timer10HzTasks.start(100);
    _timer50HzTasks.start(20);
Don Gagne's avatar
Don Gagne committed
    exec();
dogmaphobic's avatar
dogmaphobic committed
    QObject::disconnect(&_timer1HzTasks,  &QTimer::timeout, this, &MockLink::_run1HzTasks);
    QObject::disconnect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
    QObject::disconnect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks);
    _missionItemHandler.shutdown();
Don Gagne's avatar
Don Gagne committed
}

void MockLink::_run1HzTasks(void)
{
    if (_mavlinkStarted && _connected) {
Don Gagne's avatar
Don Gagne committed
        _sendHeartBeat();
Don Gagne's avatar
Don Gagne committed
        _sendVibration();
        if (_sendHomePositionDelayCount > 0) {
            // We delay home position a bit to be more realistic
            _sendHomePositionDelayCount--;
        } else {
            _sendHomePosition();
        }
        if (_sendStatusText) {
            _sendStatusText = false;
            _sendStatusTextMessages();
        }
Don Gagne's avatar
Don Gagne committed
    }
}

void MockLink::_run10HzTasks(void)
{
    if (_mavlinkStarted && _connected) {
Don Gagne's avatar
Don Gagne committed
        _sendGpsRawInt();
Don Gagne's avatar
Don Gagne committed
    }
}

void MockLink::_run50HzTasks(void)
{
    if (_mavlinkStarted && _connected) {
Don Gagne's avatar
Don Gagne committed
    }
}

void MockLink::_loadParams(void)
Loading
Loading full blame...