Skip to content
Snippets Groups Projects
UAS.cc 83 KiB
Newer Older
  • Learn to ignore specific revisions
  • lm's avatar
    lm committed
    void UAS::setHomePosition(double lat, double lon, double alt)
    {
    
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText("Setting new World Coordinate Frame Origin");
        msgBox.setInformativeText("Do you want to set a new origin? Waypoints defined in the local frame will be shifted in their physical location");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Cancel);
        int ret = msgBox.exec();
    
        // Close the message box shortly after the click to prevent accidental clicks
        QTimer::singleShot(5000, &msgBox, SLOT(reject()));
    
    
        if (ret == QMessageBox::Yes)
        {
            mavlink_message_t msg;
            mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0, MAV_CMD_DO_SET_HOME, 1, 0, 0, 0, 0, lat, lon, alt);
            // Send message twice to increase chance that it reaches its goal
            sendMessage(msg);
            // Wait 15 ms
            QGC::SLEEP::usleep(15000);
            // Send again
            sendMessage(msg);
    
            // Send new home position to UAS
            mavlink_set_gps_global_origin_t home;
            home.target_system = uasId;
            home.latitude = lat*1E7;
            home.longitude = lon*1E7;
            home.altitude = alt*1000;
            qDebug() << "lat:" << home.latitude << " lon:" << home.longitude;
            mavlink_msg_set_gps_global_origin_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &home);
            sendMessage(msg);
        }
    
    void UAS::setLocalOriginAtCurrentGPSPosition()
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText("Setting new World Coordinate Frame Origin");
        msgBox.setInformativeText("Do you want to set a new origin? Waypoints defined in the local frame will be shifted in their physical location");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Cancel);
        int ret = msgBox.exec();
    
        // Close the message box shortly after the click to prevent accidental clicks
        QTimer::singleShot(5000, &msgBox, SLOT(reject()));
    
    
    
            mavlink_message_t msg;
            mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0, MAV_CMD_DO_SET_HOME, 1, 1, 0, 0, 0, 0, 0, 0);
            // Send message twice to increase chance that it reaches its goal
            sendMessage(msg);
            // Wait 15 ms
            QGC::SLEEP::usleep(15000);
            // Send again
            sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    void UAS::setLocalPositionSetpoint(float x, float y, float z, float yaw)
    {
    
    pixhawk's avatar
    pixhawk committed
        mavlink_message_t msg;
    
    LM's avatar
    LM committed
        mavlink_msg_set_local_position_setpoint_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, MAV_FRAME_LOCAL_NED, x, y, z, yaw/M_PI*180.0);
    
    pixhawk's avatar
    pixhawk committed
        sendMessage(msg);
    
    lm's avatar
    lm committed
        Q_UNUSED(x);
        Q_UNUSED(y);
        Q_UNUSED(z);
        Q_UNUSED(yaw);
    
    pixhawk's avatar
    pixhawk committed
    void UAS::setLocalPositionOffset(float x, float y, float z, float yaw)
    {
    
    lm's avatar
    lm committed
    #ifdef MAVLINK_ENABLED_PIXHAWK
    
        mavlink_msg_set_position_control_offset_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, x, y, z, yaw);
    
    lm's avatar
    lm committed
    #else
    
        Q_UNUSED(x);
        Q_UNUSED(y);
        Q_UNUSED(z);
        Q_UNUSED(yaw);
    
    pixhawk's avatar
    pixhawk committed
    #endif
    }
    
    void UAS::startRadioControlCalibration()
    
    lm's avatar
    lm committed
    {
    
        mavlink_message_t msg;
        // Param 1: gyro cal, param 2: mag cal, param 3: pressure cal, Param 4: radio
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0, 0, 0, 1, 0, 0, 0);
    
        sendMessage(msg);
    
    void UAS::startDataRecording()
    
    lm's avatar
    lm committed
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, MAV_CMD_DO_CONTROL_VIDEO, 1, -1, -1, -1, 2, 0, 0, 0);
    
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    void UAS::stopDataRecording()
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, MAV_CMD_DO_CONTROL_VIDEO, 1, -1, -1, -1, 0, 0, 0, 0);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    void UAS::startMagnetometerCalibration()
    {
    
        mavlink_message_t msg;
        // Param 1: gyro cal, param 2: mag cal, param 3: pressure cal, Param 4: radio
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0, 1, 0, 0, 0, 0, 0);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::startGyroscopeCalibration()
    {
    
        mavlink_message_t msg;
        // Param 1: gyro cal, param 2: mag cal, param 3: pressure cal, Param 4: radio
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1, 0, 0, 0, 0, 0, 0);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::startPressureCalibration()
    {
    
        mavlink_message_t msg;
        // Param 1: gyro cal, param 2: mag cal, param 3: pressure cal, Param 4: radio
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0, 0, 1, 0, 0, 0, 0);
    
        sendMessage(msg);
    
    LM's avatar
    LM committed
    quint64 UAS::getUnixReferenceTime(quint64 time)
    {
        // Same as getUnixTime, but does not react to attitudeStamped mode
        if (time == 0)
        {
            //        qDebug() << "XNEW time:" <<QGC::groundTimeMilliseconds();
            return QGC::groundTimeMilliseconds();
        }
        // Check if time is smaller than 40 years,
        // assuming no system without Unix timestamp
        // runs longer than 40 years continuously without
        // reboot. In worst case this will add/subtract the
        // communication delay between GCS and MAV,
        // it will never alter the timestamp in a safety
        // critical way.
        //
        // Calculation:
        // 40 years
        // 365 days
        // 24 hours
        // 60 minutes
        // 60 seconds
        // 1000 milliseconds
        // 1000 microseconds
    #ifndef _MSC_VER
        else if (time < 1261440000000000LLU)
    #else
            else if (time < 1261440000000000)
    #endif
            {
            //        qDebug() << "GEN time:" << time/1000 + onboardTimeOffset;
            if (onboardTimeOffset == 0)
            {
                onboardTimeOffset = QGC::groundTimeMilliseconds() - time/1000;
            }
            return time/1000 + onboardTimeOffset;
        }
        else
        {
            // Time is not zero and larger than 40 years -> has to be
            // a Unix epoch timestamp. Do nothing.
            return time/1000;
        }
    }
    
    
    /**
     * @warning If attitudeStamped is enabled, this function will not actually return the precise time stamp
     *          of this measurement augmented to UNIX time, but will MOVE the timestamp IN TIME to match
     *          the last measured attitude. There is no reason why one would want this, except for
     *          system setups where the onboard clock is not present or broken and datasets should
     *          be collected that are still roughly synchronized. PLEASE NOTE THAT ENABLING ATTITUDE STAMPED
     *          RUINS THE SCIENTIFIC NATURE OF THE CORRECT LOGGING FUNCTIONS OF QGROUNDCONTROL!
     */
    quint64 UAS::getUnixTimeFromMs(quint64 time)
    {
        return getUnixTime(time*1000);
    }
    
    
    LM's avatar
    LM committed
    /**
     * @warning If attitudeStamped is enabled, this function will not actually return the precise time stamp
     *          of this measurement augmented to UNIX time, but will MOVE the timestamp IN TIME to match
     *          the last measured attitude. There is no reason why one would want this, except for
     *          system setups where the onboard clock is not present or broken and datasets should
     *          be collected that are still roughly synchronized. PLEASE NOTE THAT ENABLING ATTITUDE STAMPED
     *          RUINS THE SCIENTIFIC NATURE OF THE CORRECT LOGGING FUNCTIONS OF QGROUNDCONTROL!
     */
    
    quint64 UAS::getUnixTime(quint64 time)
    {
    
        quint64 ret = 0;
    
    LM's avatar
    LM committed
        if (attitudeStamped)
        {
    
            ret = lastAttitude;
    
    LM's avatar
    LM committed
        }
    
            ret = QGC::groundTimeMilliseconds();
    
        }
        // Check if time is smaller than 40 years,
        // assuming no system without Unix timestamp
        // runs longer than 40 years continuously without
        // reboot. In worst case this will add/subtract the
        // communication delay between GCS and MAV,
        // it will never alter the timestamp in a safety
        // critical way.
        //
        // Calculation:
        // 40 years
        // 365 days
        // 24 hours
        // 60 minutes
        // 60 seconds
        // 1000 milliseconds
        // 1000 microseconds
    
        else if (time < 1261440000000000LLU)
    
    LM's avatar
    LM committed
            else if (time < 1261440000000000)
    
    LM's avatar
    LM committed
            {
            //        qDebug() << "GEN time:" << time/1000 + onboardTimeOffset;
    
    LM's avatar
    LM committed
                onboardTimeOffset = QGC::groundTimeMilliseconds() - time/1000;
    
            ret = time/1000 + onboardTimeOffset;
    
            // Time is not zero and larger than 40 years -> has to be
            // a Unix epoch timestamp. Do nothing.
    
            ret = time/1000;
    
        return ret;
    
    QList<QString> UAS::getParameterNames(int component)
    {
    
            return parameters.value(component)->keys();
    
            return QList<QString>();
        }
    }
    
    QList<int> UAS::getComponentIds()
    {
        return parameters.keys();
    }
    
    
    pixhawk's avatar
    pixhawk committed
    void UAS::setMode(int mode)
    
    pixhawk's avatar
    pixhawk committed
    {
    
    LM's avatar
    LM committed
        //this->mode = mode; //no call assignament, update receive message from UAS
        mavlink_message_t msg;
        mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, (uint8_t)mode, (uint16_t)navMode);
        sendMessage(msg);
        qDebug() << "SENDING REQUEST TO SET MODE TO SYSTEM" << uasId << ", REQUEST TO SET MODE " << (uint8_t)mode;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::sendMessage(mavlink_message_t message)
    {
        // Emit message on all links that are currently connected
    
        foreach (LinkInterface* link, *links)
        {
            if (link)
            {
    
                sendMessage(link, message);
    
                // Remove from list
                links->removeAt(links->indexOf(link));
            }
    
    pixhawk's avatar
    pixhawk committed
        }
    }
    
    
    void UAS::forwardMessage(mavlink_message_t message)
    {
        // Emit message on all links that are currently connected
        QList<LinkInterface*>link_list = LinkManager::instance()->getLinksForProtocol(mavlink);
    
        foreach(LinkInterface* link, link_list)
        {
            if (link)
            {
    
                SerialLink* serial = dynamic_cast<SerialLink*>(link);
    
                if(serial != 0)
                {
                    for(int i=0; i<links->size(); i++)
                    {
                        if(serial != links->at(i))
                        {
    
                            qDebug()<<"Antenna tracking: Forwarding Over link: "<<serial->getName()<<" "<<serial;
    
                            sendMessage(serial, message);
                        }
    
    pixhawk's avatar
    pixhawk committed
    void UAS::sendMessage(LinkInterface* link, mavlink_message_t message)
    {
    
        if(!link) return;
    
    pixhawk's avatar
    pixhawk committed
        // Create buffer
        uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
        // Write message into buffer, prepending start sign
    
    pixhawk's avatar
    pixhawk committed
        int len = mavlink_msg_to_send_buffer(buffer, &message);
    
    lm's avatar
    lm committed
        static uint8_t messageKeys[256] = MAVLINK_MESSAGE_CRCS;
        mavlink_finalize_message_chan(&message, mavlink->getSystemId(), mavlink->getComponentId(), link->getId(), message.len, messageKeys[message.msgid]);
    
    pixhawk's avatar
    pixhawk committed
        // If link is connected
    
    pixhawk's avatar
    pixhawk committed
            // Send the portion of the buffer now occupied by the message
            link->writeBytes((const char*)buffer, len);
        }
    }
    
    /**
     * @param value battery voltage
     */
    
    float UAS::filterVoltage(float value) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
        return lpVoltage * 0.7f + value * 0.3f;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    QString UAS::getNavModeText(int mode)
    {
    
    lm's avatar
    lm committed
        if (autopilot == MAV_AUTOPILOT_PIXHAWK)
        {
    
    lm's avatar
    lm committed
        case 0:
    
            return QString("PREFLIGHT");
    
            break;
        default:
            return QString("UNKNOWN");
        }
    
    lm's avatar
    lm committed
        }
        else if (autopilot == MAV_AUTOPILOT_ARDUPILOTMEGA)
        {
            return QString("UNKNOWN");
        }
        else if (autopilot == MAV_AUTOPILOT_OPENPILOT)
        {
            return QString("UNKNOWN");
        }
    
        // If nothing matches, return unknown
        return QString("UNKNOWN");
    
    pixhawk's avatar
    pixhawk committed
    void UAS::getStatusForCode(int statusCode, QString& uasState, QString& stateDescription)
    {
    
    lm's avatar
    lm committed
        case MAV_STATE_UNINIT:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("UNINIT");
    
            stateDescription = tr("Unitialized, booting up.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_BOOT:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("BOOT");
    
            stateDescription = tr("Booting system, please wait.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_CALIBRATING:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("CALIBRATING");
    
            stateDescription = tr("Calibrating sensors, please wait.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_ACTIVE:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("ACTIVE");
    
            stateDescription = tr("Active, normal operation.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_STANDBY:
            uasState = tr("STANDBY");
    
            stateDescription = tr("Standby mode, ready for liftoff.");
    
    lm's avatar
    lm committed
            break;
        case MAV_STATE_CRITICAL:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("CRITICAL");
    
            stateDescription = tr("FAILURE: Continuing operation.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_EMERGENCY:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("EMERGENCY");
    
            stateDescription = tr("EMERGENCY: Land Immediately!");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    James Goppert's avatar
    James Goppert committed
            //case MAV_STATE_HILSIM:
    
    James Goppert's avatar
    James Goppert committed
            //uasState = tr("HIL SIM");
            //stateDescription = tr("HIL Simulation, Sensors read from SIM");
            //break;
    
    lm's avatar
    lm committed
        case MAV_STATE_POWEROFF:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("SHUTDOWN");
    
            stateDescription = tr("Powering off system.");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        default:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("UNKNOWN");
    
            stateDescription = tr("Unknown system state");
    
    pixhawk's avatar
    pixhawk committed
            break;
        }
    }
    
    
    QImage UAS::getImage()
    {
    
    LM's avatar
    LM committed
    #ifdef MAVLINK_ENABLED_PIXHAWK
    
        qDebug() << "IMAGE TYPE:" << imageType;
    
        // RAW greyscale
        if (imageType == MAVLINK_DATA_STREAM_IMG_RAW8U)
        {
    
    LM's avatar
    LM committed
            // TODO FIXME
            int imgColors = 255;//imageSize/(imageWidth*imageHeight);
    
    LM's avatar
    LM committed
            //const int headerSize = 15;
    
            // Construct PGM header
            QString header("P5\n%1 %2\n%3\n");
    
    LM's avatar
    LM committed
            header = header.arg(imageWidth).arg(imageHeight).arg(imgColors);
    
    LM's avatar
    LM committed
    
            QByteArray tmpImage(header.toStdString().c_str(), header.toStdString().size());
            tmpImage.append(imageRecBuffer);
    
            //qDebug() << "IMAGE SIZE:" << tmpImage.size() << "HEADER SIZE: (15):" << header.size() << "HEADER: " << header;
    
            if (imageRecBuffer.isNull())
            {
                qDebug()<< "could not convertToPGM()";
                return QImage();
            }
    
            if (!image.loadFromData(tmpImage, "PGM"))
            {
                qDebug()<< "could not create extracted image";
                return QImage();
            }
    
        }
        // BMP with header
        else if (imageType == MAVLINK_DATA_STREAM_IMG_BMP ||
                 imageType == MAVLINK_DATA_STREAM_IMG_JPEG ||
                 imageType == MAVLINK_DATA_STREAM_IMG_PGM ||
                 imageType == MAVLINK_DATA_STREAM_IMG_PNG)
        {
           if (!image.loadFromData(imageRecBuffer))
            {
               qDebug() << "Loading data from image buffer failed!";
            }
        }
    
    pixhawk's avatar
    pixhawk committed
        // Restart statemachine
        imagePacketsArrived = 0;
    
    LM's avatar
    LM committed
        //imageRecBuffer.clear();
    
        return image;
    
    LM's avatar
    LM committed
    #endif
    
    }
    
    void UAS::requestImage()
    {
    
    #ifdef MAVLINK_ENABLED_PIXHAWK
    
        qDebug() << "trying to get an image from the uas...";
    
    
        // check if there is already an image transmission going on
        if (imagePacketsArrived == 0)
        {
    
            mavlink_message_t msg;
    
    LM's avatar
    LM committed
            mavlink_msg_data_transmission_handshake_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, DATA_TYPE_JPEG_IMAGE, 0, 0, 0, 0, 0, 50);
    
            sendMessage(msg);
        }
    
    pixhawk's avatar
    pixhawk committed
    
    
    /* MANAGEMENT */
    
    /*
     *
     * @return The uptime in milliseconds
     *
     **/
    
    pixhawk's avatar
    pixhawk committed
    {
    
    pixhawk's avatar
    pixhawk committed
            return 0;
    
    pixhawk's avatar
    pixhawk committed
            return MG::TIME::getGroundTimeNow() - startTime;
        }
    }
    
    
    int UAS::getCommunicationStatus() const
    
    pixhawk's avatar
    pixhawk committed
    {
        return commStatus;
    }
    
    
    void UAS::requestParameters()
    {
        mavlink_message_t msg;
    
        mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 25);
    
        sendMessage(msg);
    
    void UAS::writeParametersToStorage()
    
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, MAV_CMD_PREFLIGHT_STORAGE, 1, 1, -1, -1, -1, 0, 0, 0);
    
    pixhawk's avatar
    pixhawk committed
        qDebug() << "SENT COMMAND" << MAV_CMD_PREFLIGHT_STORAGE;
    
        sendMessage(msg);
    
    }
    
    void UAS::readParametersFromStorage()
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 0, MAV_CMD_PREFLIGHT_STORAGE, 1, 0, -1, -1, -1, 0, 0, 0);
    
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableAllDataTransmission(int rate)
    
    lm's avatar
    lm committed
    {
        // Buffers to write data to
    
        mavlink_request_data_stream_t stream;
    
    lm's avatar
    lm committed
        // Select the message to request from now on
        // 0 is a magic ID and will enable/disable the standard message set except for heartbeat
    
        stream.req_stream_id = MAV_DATA_STREAM_ALL;
    
    lm's avatar
    lm committed
        // Select the update rate in Hz the message should be send
        // All messages will be send with their default rate
    
    James Goppert's avatar
    James Goppert committed
        // TODO: use 0 to turn off and get rid of enable/disable? will require
        //  a different magic flag for turning on defaults, possibly something really high like 1111 ?
    
    lm's avatar
    lm committed
        stream.req_message_rate = 0;
        // Start / stop the message
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
    lm's avatar
    lm committed
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
    
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableRawSensorDataTransmission(int rate)
    
    lm's avatar
    lm committed
    {
        // Buffers to write data to
        mavlink_message_t msg;
    
        mavlink_request_data_stream_t stream;
    
    lm's avatar
    lm committed
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_RAW_SENSORS;
    
    lm's avatar
    lm committed
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    lm's avatar
    lm committed
        // Start / stop the message
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
    lm's avatar
    lm committed
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
    
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableExtendedSystemStatusTransmission(int rate)
    
    lm's avatar
    lm committed
    {
    
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_EXTENDED_STATUS;
    
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableRCChannelDataTransmission(int rate)
    
    lm's avatar
    lm committed
    {
    
    #if defined(MAVLINK_ENABLED_UALBERTA_MESSAGES)
        mavlink_message_t msg;
        mavlink_msg_request_rc_channels_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, enabled);
        sendMessage(msg);
    #else
    
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_RC_CHANNELS;
    
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableRawControllerDataTransmission(int rate)
    
    lm's avatar
    lm committed
    {
    
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_RAW_CONTROLLER;
    
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    
    lm's avatar
    lm committed
    //void UAS::enableRawSensorFusionTransmission(int rate)
    //{
    //    // Buffers to write data to
    //    mavlink_message_t msg;
    //    mavlink_request_data_stream_t stream;
    //    // Select the message to request from now on
    //    stream.req_stream_id = MAV_DATA_STREAM_RAW_SENSOR_FUSION;
    //    // Select the update rate in Hz the message should be send
    //    stream.req_message_rate = rate;
    //    // Start / stop the message
    //    stream.start_stop = (rate) ? 1 : 0;
    //    // The system which should take this command
    //    stream.target_system = uasId;
    //    // The component / subsystem which should take this command
    //    stream.target_component = 0;
    //    // Encode and send the message
    //    mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    //    // Send message twice to increase chance of reception
    //    sendMessage(msg);
    //    sendMessage(msg);
    //}
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enablePositionTransmission(int rate)
    
    pixhawk's avatar
    pixhawk committed
    {
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_POSITION;
    
    pixhawk's avatar
    pixhawk committed
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    pixhawk's avatar
    pixhawk committed
        // Start / stop the message
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
    pixhawk's avatar
    pixhawk committed
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
        // Send message twice to increase chance of reception
        sendMessage(msg);
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableExtra1Transmission(int rate)
    
    pixhawk's avatar
    pixhawk committed
    {
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_EXTRA1;
    
    pixhawk's avatar
    pixhawk committed
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    pixhawk's avatar
    pixhawk committed
        // Start / stop the message
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
    pixhawk's avatar
    pixhawk committed
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableExtra2Transmission(int rate)
    
    pixhawk's avatar
    pixhawk committed
    {
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_EXTRA2;
    
    pixhawk's avatar
    pixhawk committed
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    pixhawk's avatar
    pixhawk committed
        // Start / stop the message
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
    pixhawk's avatar
    pixhawk committed
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    }
    
    
    James Goppert's avatar
    James Goppert committed
    void UAS::enableExtra3Transmission(int rate)
    
    pixhawk's avatar
    pixhawk committed
    {
        // Buffers to write data to
        mavlink_message_t msg;
        mavlink_request_data_stream_t stream;
        // Select the message to request from now on
    
        stream.req_stream_id = MAV_DATA_STREAM_EXTRA3;
    
    pixhawk's avatar
    pixhawk committed
        // Select the update rate in Hz the message should be send
    
    James Goppert's avatar
    James Goppert committed
        stream.req_message_rate = rate;
    
    James Goppert's avatar
    James Goppert committed
        stream.start_stop = (rate) ? 1 : 0;
    
        // The system which should take this command
        stream.target_system = uasId;
        // The component / subsystem which should take this command
        stream.target_component = 0;
        // Encode and send the message
        mavlink_msg_request_data_stream_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &stream);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    lm's avatar
    lm committed
    /**
     * Set a parameter value onboard
     *
     * @param component The component to set the parameter
     * @param id Name of the parameter
     * @param value Parameter value
     */
    
    void UAS::setParameter(const int component, const QString& id, const QVariant& value)
    
    lm's avatar
    lm committed
    {
    
            mavlink_message_t msg;
            mavlink_param_set_t p;
    
            mavlink_param_union_t union_value;
    
            // Assign correct value based on QVariant
            switch (value.type())
            {
            case QVariant::Int:
                union_value.param_int32 = value.toInt();
    
                p.param_type = MAVLINK_TYPE_INT32_T;
    
                break;
            case QVariant::UInt:
                union_value.param_uint32 = value.toUInt();
    
                p.param_type = MAVLINK_TYPE_UINT32_T;
    
                break;
            case QMetaType::Float:
                union_value.param_float = value.toFloat();
    
                p.param_type = MAVLINK_TYPE_FLOAT;
    
                break;
            default:
                qCritical() << "ABORTED PARAM SEND, NO VALID QVARIANT TYPE";
                return;
            }
    
            p.param_value = union_value.param_float;
    
            p.target_system = (uint8_t)uasId;
            p.target_component = (uint8_t)component;
    
    
            qDebug() << "SENT PARAM:" << value;
    
    
            // Copy string into buffer, ensuring not to exceed the buffer size
    
            for (unsigned int i = 0; i < sizeof(p.param_id); i++)
            {
    
                // String characters
    
                if ((int)i < id.length() && i < (sizeof(p.param_id) - 1))
                {
    
                    p.param_id[i] = id.toAscii()[i];
                }
    
    LM's avatar
    LM committed
                //        // Null termination at end of string or end of buffer
                //        else if ((int)i == id.length() || i == (sizeof(p.param_id) - 1))
                //        {
                //            p.param_id[i] = '\0';
                //        }
    
                // Zero fill
    
                    p.param_id[i] = 0;
                }
    
    lm's avatar
    lm committed
            }
    
            mavlink_msg_param_set_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &p);
            sendMessage(msg);
    
    lm's avatar
    lm committed
        }
    
    void UAS::requestParameter(int component, int id)
    {
        // Request parameter, use parameter name to request it
        mavlink_message_t msg;
        mavlink_param_request_read_t read;
        read.param_index = id;
        read.param_id[0] = '\0'; // Enforce null termination
        read.target_system = uasId;
        read.target_component = component;
        mavlink_msg_param_request_read_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &read);
        sendMessage(msg);
        qDebug() << __FILE__ << __LINE__ << "REQUESTING PARAM RETRANSMISSION FROM COMPONENT" << component << "FOR PARAM ID" << id;
    }
    
    
    void UAS::requestParameter(int component, const QString& parameter)
    
        // Request parameter, use parameter name to request it
    
        mavlink_message_t msg;
        mavlink_param_request_read_t read;
    
        read.param_index = -1;
        // Copy full param name or maximum max field size
        if (parameter.length() > MAVLINK_MSG_PARAM_REQUEST_READ_FIELD_PARAM_ID_LEN)
        {
            emit textMessageReceived(uasId, 0, 255, QString("QGC WARNING: Parameter name %1 is more than %2 bytes long. This might lead to errors and mishaps!").arg(parameter).arg(MAVLINK_MSG_PARAM_REQUEST_READ_FIELD_PARAM_ID_LEN-1));
        }
        memcpy(read.param_id, parameter.toStdString().c_str(), qMax(parameter.length(), MAVLINK_MSG_PARAM_REQUEST_READ_FIELD_PARAM_ID_LEN));
        read.param_id[15] = '\0'; // Enforce null termination
    
        read.target_system = uasId;
        read.target_component = component;
        mavlink_msg_param_request_read_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &read);
        sendMessage(msg);
    
        qDebug() << __FILE__ << __LINE__ << "REQUESTING PARAM RETRANSMISSION FROM COMPONENT" << component << "FOR PARAM NAME" << parameter;
    
    void UAS::setSystemType(int systemType)
    {
        type = systemType;
        // If the airframe is still generic, change it to a close default type
    
    lm's avatar
    lm committed
            case MAV_TYPE_FIXED_WING:
    
                airframe = QGC_AIRFRAME_EASYSTAR;
                break;
    
    lm's avatar
    lm committed
            case MAV_TYPE_QUADROTOR:
    
                airframe = QGC_AIRFRAME_MIKROKOPTER;
                break;
            }
        }
        emit systemSpecsChanged(uasId);
    }
    
    
    void UAS::setUASName(const QString& name)
    {
    
    lm's avatar
    lm committed
        if (name != "")
        {
            this->name = name;
            writeSettings();
            emit nameChanged(name);
            emit systemSpecsChanged(uasId);
        }
    
    lm's avatar
    lm committed
    void UAS::executeCommand(MAV_CMD command)
    {
        mavlink_message_t msg;
    
        cmd.command = (uint8_t)command;
        cmd.confirmation = 0;
        cmd.param1 = 0.0f;
        cmd.param2 = 0.0f;
        cmd.param3 = 0.0f;
        cmd.param4 = 0.0f;
    
        cmd.param5 = 0.0f;
        cmd.param6 = 0.0f;
        cmd.param7 = 0.0f;
    
        cmd.target_system = uasId;
        cmd.target_component = 0;
    
        mavlink_msg_command_long_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &cmd);
    
        sendMessage(msg);
    }
    
    
    void UAS::executeCommand(MAV_CMD command, int confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7, int component)
    {
        mavlink_message_t msg;
        mavlink_command_long_t cmd;
    
        cmd.command = (uint8_t)command;
        cmd.confirmation = confirmation;
        cmd.param1 = param1;
        cmd.param2 = param2;
        cmd.param3 = param3;
        cmd.param4 = param4;
    
        cmd.param5 = param5;
        cmd.param6 = param6;
        cmd.param7 = param7;
    
        cmd.target_system = uasId;
        cmd.target_component = component;
    
        mavlink_msg_command_long_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &cmd);
    
    lm's avatar
    lm committed
        sendMessage(msg);
    }
    
    
    pixhawk's avatar
    pixhawk committed
    /**
    
    lm's avatar
    lm committed
     * Launches the system
    
    pixhawk's avatar
    pixhawk committed
     *
     **/
    void UAS::launch()
    {
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0, MAV_CMD_NAV_TAKEOFF, 1, 0, 0, 0, 0, 0, 0, 0);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * Depending on the UAS, this might make the rotors of a helicopter spinning
     *
     **/
    
    void UAS::armSystem()
    
    pixhawk's avatar
    pixhawk committed
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode, navMode | MAV_MODE_FLAG_SAFETY_ARMED);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * @warning Depending on the UAS, this might completely stop all motors.
     *
     **/
    
    void UAS::disarmSystem()
    
    pixhawk's avatar
    pixhawk committed
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode, navMode & !MAV_MODE_FLAG_SAFETY_ARMED);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::setManualControlCommands(double roll, double pitch, double yaw, double thrust)
    {
        // Scale values
        double rollPitchScaling = 0.2f;
        double yawScaling = 0.5f;
        double thrustScaling = 1.0f;
    
        manualRollAngle = roll * rollPitchScaling;
        manualPitchAngle = pitch * rollPitchScaling;
        manualYawAngle = yaw * yawScaling;
        manualThrust = thrust * thrustScaling;
    
    
    LM's avatar
    LM committed
        // If system has manual inputs enabled and is armed
        if((mode & MAV_MODE_FLAG_DECODE_POSITION_MANUAL) && (mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY))
    
            mavlink_message_t message;
            mavlink_msg_manual_control_pack(mavlink->getSystemId(), mavlink->getComponentId(), &message, this->uasId, (float)manualRollAngle, (float)manualPitchAngle, (float)manualYawAngle, (float)manualThrust, controlRollManual, controlPitchManual, controlYawManual, controlThrustManual);
            sendMessage(message);
            qDebug() << __FILE__ << __LINE__ << ": SENT MANUAL CONTROL MESSAGE: roll" << manualRollAngle << " pitch: " << manualPitchAngle << " yaw: " << manualYawAngle << " thrust: " << manualThrust;
    
    pixhawk's avatar
    pixhawk committed
    
    
            emit attitudeThrustSetPointChanged(this, roll, pitch, yaw, thrust, MG::TIME::getGroundTimeNow());
    
            qDebug() << "JOYSTICK/MANUAL CONTROL: IGNORING COMMANDS: Set mode to MANUAL to send joystick commands first";
        }
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    pixhawk's avatar
    pixhawk committed
    void UAS::receiveButton(int buttonIndex)
    {