WatchdogControl.cc 6.77 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 Implementation of class WatchdogControl
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

31
#include "WatchdogControl.h"
32 33
#include "WatchdogView.h"
#include "WatchdogProcessView.h"
34
#include "ui_WatchdogControl.h"
35
#include "PxQuadMAV.h"
36

37 38
#include "UASManager.h"

39 40
#include <QDebug>

lm's avatar
lm committed
41
WatchdogControl::WatchdogControl(QWidget *parent) :
42 43 44 45
    QWidget(parent),
    mav(NULL),
    updateInterval(2000000),
    ui(new Ui::WatchdogControl)
46 47
{
    ui->setupUi(this);
pixhawk's avatar
pixhawk committed
48 49

    // UI is initialized, setup layout
50
    listLayout = new QVBoxLayout(ui->mainWidget);
pixhawk's avatar
pixhawk committed
51 52 53
    listLayout->setSpacing(6);
    listLayout->setMargin(0);
    listLayout->setAlignment(Qt::AlignTop);
54
    ui->mainWidget->setLayout(listLayout);
pixhawk's avatar
pixhawk committed
55

56
    connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(setUAS(UASInterface*)));
57 58

    this->setVisible(false);
59 60 61 62 63 64 65
}

WatchdogControl::~WatchdogControl()
{
    delete ui;
}

66 67
void WatchdogControl::setUAS(UASInterface* uas)
{
lm's avatar
lm committed
68
    PxQuadMAV* qmav = dynamic_cast<PxQuadMAV*>(uas);
69

70
    if (qmav) {
71
        connect(qmav, SIGNAL(processReceived(int,int,int,QString,QString,int)), this, SLOT(addProcess(int,int,int,QString,QString,int)));
pixhawk's avatar
pixhawk committed
72
        connect(qmav, SIGNAL(watchdogReceived(int,int,uint)), this, SLOT(updateWatchdog(int,int,uint)));
73
        connect(qmav, SIGNAL(processChanged(int,int,int,int,bool,int,int)), this, SLOT(updateProcess(int,int,int,int,bool,int,int)));
74 75 76
    }
}

77 78 79
void WatchdogControl::updateWatchdog(int systemId, int watchdogId, unsigned int processCount)
{
    // request the watchdog with the given ID
pixhawk's avatar
pixhawk committed
80
    // Get the watchdog and request the info for it
81 82 83
    WatchdogInfo& watchdog = this->getWatchdog(systemId, watchdogId);

    // if the proces count doesn't match, the watchdog is either new or has changed - create a new vector with new (and empty) ProcessInfo structs.
84
    if (watchdog.processes_.size() != processCount) {
85
        watchdog.processes_ = std::vector<ProcessInfo>(processCount);
pixhawk's avatar
pixhawk committed
86
        // Create new UI widget
87 88
        //WatchdogView* view = new WatchdogView(this);

pixhawk's avatar
pixhawk committed
89
    }
90 91 92

    // start the timeout timer
    //watchdog.timeoutTimer_.reset();
pixhawk's avatar
pixhawk committed
93

pixhawk's avatar
pixhawk committed
94
    qDebug() << "WATCHDOG RECEIVED";
95 96 97 98 99 100 101 102 103 104 105 106 107
    //qDebug() << "<-- received mavlink_watchdog_heartbeat_t " << msg->sysid << " / " << payload.watchdog_id << " / " << payload.process_count << std::endl;
}

void WatchdogControl::addProcess(int systemId, int watchdogId, int processId, QString name, QString arguments, int timeout)
{
    // request the watchdog and the process with the given IDs
    WatchdogInfo& watchdog = this->getWatchdog(systemId, watchdogId);
    ProcessInfo& process = watchdog.getProcess(processId);

    // store the process information in the ProcessInfo struct
    process.name_ = name.toStdString();
    process.arguments_ = arguments.toStdString();
    process.timeout_ = timeout;
108
    qDebug() << "PROCESS RECEIVED";
pixhawk's avatar
pixhawk committed
109
    qDebug() << "SYS" << systemId << "WD" << watchdogId << "PROCESS" << processId << name << "ARG" << arguments << "TO" << timeout;
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    //qDebug() << "<-- received mavlink_watchdog_process_info_t " << msg->sysid << " / " << (const char*)payload.name << " / " << (const char*)payload.arguments << " / " << payload.timeout << std::endl;
}


void WatchdogControl::updateProcess(int systemId, int watchdogId, int processId, int state, bool muted, int crashes, int pid)
{
    // request the watchdog and the process with the given IDs
    WatchdogInfo& watchdog = this->getWatchdog(systemId, watchdogId);
    ProcessInfo& process = watchdog.getProcess(processId);

    // store the status information in the ProcessInfo struct
    process.state_ = static_cast<ProcessInfo::State::Enum>(state);
    process.muted_ = muted;
    process.crashes_ = crashes;
    process.pid_ = pid;

126
    qDebug() << "PROCESS UPDATED";
pixhawk's avatar
pixhawk committed
127 128
    qDebug() << "SYS" << systemId << "WD" << watchdogId << "PROCESS" << processId << "STATE" << state << "CRASH" << crashes << "PID" << pid;

129 130 131 132 133 134 135 136 137 138 139 140
    //process.updateTimer_.reset();
    //qDebug() << "<-- received mavlink_watchdog_process_status_t " << msg->sysid << " / " << payload.state << " / " << payload.muted << " / " << payload.crashes << " / " << payload.pid << std::endl;
}

/**
    @brief Returns a WatchdogInfo struct that belongs to the watchdog with the given system-ID and watchdog-ID
*/
WatchdogControl::WatchdogInfo& WatchdogControl::getWatchdog(uint8_t systemId, uint16_t watchdogId)
{
    WatchdogID id(systemId, watchdogId);

    std::map<WatchdogID, WatchdogInfo>::iterator it = this->watchdogs_.find(id);
141
    if (it != this->watchdogs_.end()) {
142 143
        // the WatchdogInfo struct already exists in the map, return it
        return it->second;
144
    } else {
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
        // the WatchdogInfo struct doesn't exist - request info and status for all processes and create the struct
        this->sendCommand(id, WatchdogControl::ALL, Command::RequestInfo);
        this->sendCommand(id, WatchdogControl::ALL, Command::RequestStatus);
        return this->watchdogs_[id];
    }
}

/**
    @brief Returns a ProcessInfo struct that belongs to the process with the given ID.
*/
WatchdogControl::ProcessInfo& WatchdogControl::WatchdogInfo::getProcess(uint16_t index)
{
    // if the index is out of bounds, resize the vector
    if (index >= this->processes_.size())
        this->processes_.resize(index + 1);

    return this->processes_[index];
}

/**
    @brief Sends a watchdog command to a process on a given watchdog.
    @param w_id The WatchdogID struct (containing system-ID and watchdog-ID) that identifies the watchdog
    @param p_id The process-ID
    @param command The command-ID
*/
void WatchdogControl::sendCommand(const WatchdogID& w_id, uint16_t p_id, Command::Enum command)
{
172
    emit sendProcessCommand(w_id.watchdog_id_, p_id, command);
173 174 175 176 177 178 179 180 181 182 183 184 185
}

void WatchdogControl::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}