Skip to content
Snippets Groups Projects
UAS.cc 76.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •     mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_REC_START);
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    void UAS::pauseDataRecording()
    {
    
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_REC_PAUSE);
        sendMessage(msg);
    
    lm's avatar
    lm committed
    }
    
    void UAS::stopDataRecording()
    {
    
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_REC_STOP);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    void UAS::startMagnetometerCalibration()
    {
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_CALIBRATE_MAG);
        sendMessage(msg);
    }
    
    void UAS::startGyroscopeCalibration()
    {
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_CALIBRATE_GYRO);
        sendMessage(msg);
    }
    
    void UAS::startPressureCalibration()
    {
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_IMU, MAV_ACTION_CALIBRATE_PRESSURE);
        sendMessage(msg);
    }
    
    
    quint64 UAS::getUnixTime(quint64 time)
    {
        if (time == 0)
        {
            return MG::TIME::getGroundTimeNow();
        }
        // 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)
    
            else if (time < 1261440000000000)
    
                onboardTimeOffset = MG::TIME::getGroundTimeNow() - 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.
    
    QList<QString> UAS::getParameterNames(int component)
    {
        if (parameters.contains(component))
        {
            return parameters.value(component)->keys();
        }
        else
        {
            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
        if ((uint8_t)mode >= MAV_MODE_LOCKED && (uint8_t)mode <= MAV_MODE_RC_TRAINING)
    
            this->mode = mode;
    
    pixhawk's avatar
    pixhawk committed
            mavlink_message_t msg;
    
    lm's avatar
    lm committed
            mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, (uint8_t)uasId, (uint8_t)mode);
    
    pixhawk's avatar
    pixhawk committed
            sendMessage(msg);
    
    lm's avatar
    lm committed
            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
        QList<LinkInterface*>::iterator i;
        for (i = links->begin(); i != links->end(); ++i)
        {
            sendMessage(*i, message);
        }
    }
    
    
    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)
        {
    
                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);
    
        mavlink_finalize_message_chan(&message, mavlink->getSystemId(), mavlink->getComponentId(), link->getId(), message.len);
    
    pixhawk's avatar
    pixhawk committed
        // If link is connected
        if (link->isConnected())
        {
            // 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
    }
    
    void UAS::getStatusForCode(int statusCode, QString& uasState, QString& stateDescription)
    {
        switch (statusCode)
        {
    
    lm's avatar
    lm committed
        case MAV_STATE_UNINIT:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("UNINIT");
    
            stateDescription = tr("Waiting..");
    
    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..");
    
    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..");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_ACTIVE:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("ACTIVE");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_STANDBY:
            uasState = tr("STANDBY");
    
            stateDescription = tr("Standby, OK");
    
    lm's avatar
    lm committed
            break;
        case MAV_STATE_CRITICAL:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("CRITICAL");
    
            stateDescription = tr("FAILURE: Continue");
    
    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!");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case MAV_STATE_POWEROFF:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("SHUTDOWN");
    
            stateDescription = tr("Powering off");
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        default:
    
    pixhawk's avatar
    pixhawk committed
            uasState = tr("UNKNOWN");
    
            stateDescription = tr("Unknown state");
    
    pixhawk's avatar
    pixhawk committed
            break;
        }
    }
    
    
    
    /* MANAGEMENT */
    
    /*
     *
     * @return The uptime in milliseconds
     *
     **/
    
    pixhawk's avatar
    pixhawk committed
    {
        if(startTime == 0) {
            return 0;
        } else {
            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);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
    
    void UAS::writeParametersToStorage()
    
        mavlink_message_t msg;
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(),MAV_COMP_ID_IMU, (uint8_t)MAV_ACTION_STORAGE_WRITE);
    
    unknown's avatar
    unknown committed
        //mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(),(uint8_t)MAV_ACTION_STORAGE_WRITE);
    
        sendMessage(msg);
    }
    
    void UAS::readParametersFromStorage()
    {
        mavlink_message_t msg;
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU,(uint8_t)MAV_ACTION_STORAGE_READ);
        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
        sendMessage(msg);
    }
    
    
    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
        sendMessage(msg);
    }
    
    
    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);
        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
     */
    
    lm's avatar
    lm committed
    void UAS::setParameter(const int component, const QString& id, const float value)
    {
        if (!id.isNull())
        {
    
        mavlink_message_t msg;
        mavlink_param_set_t p;
        p.param_value = value;
    
        p.target_system = (uint8_t)uasId;
        p.target_component = (uint8_t)component;
    
        // Copy string into buffer, ensuring not to exceed the buffer size    
    
        for (unsigned int i = 0; i < sizeof(p.param_id); i++)
    
    lm's avatar
    lm committed
            // String characters
    
            if ((int)i < id.length() && i < (sizeof(p.param_id) - 1))
    
    lm's avatar
    lm committed
            {
    
    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))
    
    lm's avatar
    lm committed
            {
                p.param_id[i] = '\0';
            }
            // Zero fill
            else
            {
                p.param_id[i] = 0;
            }
    
        mavlink_msg_param_set_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &p);
    
    lm's avatar
    lm committed
        }
    
    void UAS::setSystemType(int systemType)
    {
        type = systemType;
        // If the airframe is still generic, change it to a close default type
        if (airframe == 0)
        {
            switch (systemType)
            {
            case MAV_FIXED_WING:
                airframe = QGC_AIRFRAME_EASYSTAR;
                break;
            case MAV_QUADROTOR:
                airframe = QGC_AIRFRAME_MIKROKOPTER;
                break;
            }
        }
        emit systemSpecsChanged(uasId);
    }
    
    
    void UAS::setUASName(const QString& name)
    {
        this->name = name;
    
        emit nameChanged(name);
    
        emit systemSpecsChanged(uasId);
    
    /**
     * Sets an action
     *
     **/
    void UAS::setAction(MAV_ACTION action)
    {
        mavlink_message_t msg;
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0, action);
        // Send message twice to increase chance that it reaches its goal
        sendMessage(msg);
        sendMessage(msg);
    }
    
    
    pixhawk's avatar
    pixhawk committed
    /**
    
    lm's avatar
    lm committed
     * Launches the system
    
    pixhawk's avatar
    pixhawk committed
     *
     **/
    void UAS::launch()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_IMU, (uint8_t)MAV_ACTION_TAKEOFF);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * Depending on the UAS, this might make the rotors of a helicopter spinning
     *
     **/
    void UAS::enable_motors()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_IMU, (uint8_t)MAV_ACTION_MOTORS_START);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * @warning Depending on the UAS, this might completely stop all motors.
     *
     **/
    void UAS::disable_motors()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_IMU, (uint8_t)MAV_ACTION_MOTORS_STOP);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        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;
    
    
        if(mode == (int)MAV_MODE_MANUAL)
        {
            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());
        }
        else
        {
            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)
    {
        switch (buttonIndex)
        {
        case 0:
    
    pixhawk's avatar
    pixhawk committed
    
    
    pixhawk's avatar
    pixhawk committed
            break;
        case 1:
    
    pixhawk's avatar
    pixhawk committed
    
    
    pixhawk's avatar
    pixhawk committed
            break;
        default:
    
            break;
        }
    
        //    qDebug() << __FILE__ << __LINE__ << ": Received button clicked signal (button # is: " << buttonIndex << "), UNIMPLEMENTED IN MAVLINK!";
    
    /*void UAS::requestWaypoints()
    
    pixhawk's avatar
    pixhawk committed
    {
    //    mavlink_message_t msg;
    //    mavlink_msg_waypoint_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, 25);
    //    // Send message twice to increase chance of reception
    //    sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
        waypointManager.requestWaypoints();
        qDebug() << "UAS Request WPs";
    
    pixhawk's avatar
    pixhawk committed
    void UAS::setWaypoint(Waypoint* wp)
    {
    
    pixhawk's avatar
    pixhawk committed
    //    mavlink_message_t msg;
    //    mavlink_waypoint_set_t set;
    //    set.id = wp->id;
    //    //QString name = wp->name;
    //    // FIXME Check if this works properly
    //    //name.truncate(MAVLINK_MSG_WAYPOINT_SET_FIELD_NAME_LEN);
    //    //strcpy((char*)set.name, name.toStdString().c_str());
    //    set.autocontinue = wp->autocontinue;
    //    set.target_component = 25; // FIXME
    //    set.target_system = uasId;
    //    set.active = wp->current;
    //    set.x = wp->x;
    //    set.y = wp->y;
    //    set.z = wp->z;
    //    set.yaw = wp->yaw;
    //    mavlink_msg_waypoint_set_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &set);
    //    // Send message twice to increase chance of reception
    //    sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::setWaypointActive(int id)
    {
    
    pixhawk's avatar
    pixhawk committed
    //    mavlink_message_t msg;
    //    mavlink_waypoint_set_active_t active;
    //    active.id = id;
    //    active.target_system = uasId;
    //    active.target_component = 25; // FIXME
    //    mavlink_msg_waypoint_set_active_encode(mavlink->getSystemId(), mavlink->getComponentId(), &msg, &active);
    //    // Send message twice to increase chance of reception
    //    sendMessage(msg);
    //    sendMessage(msg);
    //    // TODO This should be not directly emitted, but rather being fed back from the UAS
    //    emit waypointSelected(getUASID(), id);
    }
    
    void UAS::clearWaypointList()
    {
    //    mavlink_message_t msg;
    //    // FIXME
    //    mavlink_waypoint_clear_list_t clist;
    //    clist.target_system = uasId;
    //    clist.target_component = 25;  // FIXME
    //    mavlink_msg_waypoint_clear_list_encode(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, &clist);
    //    sendMessage(msg);
    //    qDebug() << "UAS clears Waypoints!";
    
    pixhawk's avatar
    pixhawk committed
    
    
    void UAS::halt()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU, (int)MAV_ACTION_HALT);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    void UAS::go()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU,  (int)MAV_ACTION_CONTINUE);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /** Order the robot to return home / to land on the runway **/
    void UAS::home()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU,  (int)MAV_ACTION_RETURN);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * The MAV starts the emergency landing procedure. The behaviour depends on the onboard implementation
     * and might differ between systems.
     */
    void UAS::emergencySTOP()
    {
    
        mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
        // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
        mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU, (int)MAV_ACTION_EMCY_LAND);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     * All systems are immediately shut down (e.g. the main power line is cut).
     * @warning This might lead to a crash
     *
     * The command will not be executed until emergencyKILLConfirm is issues immediately afterwards
     */
    bool UAS::emergencyKILL()
    {
        bool result = false;
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText("EMERGENCY: KILL ALL MOTORS ON UAS");
        msgBox.setInformativeText("Do you want to cut power on all systems?");
        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;
    
    pixhawk's avatar
    pixhawk committed
            // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
            mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU, (int)MAV_ACTION_EMCY_KILL);
    
            // Send message twice to increase chance of reception
            sendMessage(msg);
            sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
            result = true;
        }
        return result;
    }
    
    void UAS::shutdown()
    {
        bool result = false;
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText("Shutting down the UAS");
        msgBox.setInformativeText("Do you want to shut down the onboard computer?");
        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)
        {
            // If the active UAS is set, execute command
    
            mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
            // TODO Replace MG System ID with static function call and allow to change ID in GUI
    
            mavlink_msg_action_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, this->getUASID(), MAV_COMP_ID_IMU,(int)MAV_ACTION_SHUTDOWN);
    
            // Send message twice to increase chance of reception
            sendMessage(msg);
            sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
            result = true;
        }
    }
    
    
    void UAS::setTargetPosition(float x, float y, float z, float yaw)
    {
    
        mavlink_message_t msg;
        mavlink_msg_position_target_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, x, y, z, yaw);
    
        // Send message twice to increase chance of reception
        sendMessage(msg);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    /**
     * @return The name of this system as string in human-readable form
     */
    
    QString UAS::getUASName(void) const
    
    pixhawk's avatar
    pixhawk committed
    {
        QString result;
        if (name == "")
        {
            result = tr("MAV ") + result.sprintf("%03d", getUASID());
        }
        else
        {
            result = name;
        }
        return result;
    }
    
    void UAS::addLink(LinkInterface* link)
    {
        if (!links->contains(link))
        {
            links->append(link);
    
            connect(link, SIGNAL(destroyed(QObject*)), this, SLOT(removeLink(QObject*)));
    
    pixhawk's avatar
    pixhawk committed
        }
        //links->append(link);
    
        //qDebug() << link<<" ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK ADDED LINK";
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    void UAS::removeLink(QObject* object)
    {
        LinkInterface* link = dynamic_cast<LinkInterface*>(object);
        if (link)
        {
            links->removeAt(links->indexOf(link));
        }
    }
    
    
    pixhawk's avatar
    pixhawk committed
    /**
     * @brief Get the links associated with this robot
     *
     **/
    QList<LinkInterface*>* UAS::getLinks()
    {
        return links;
    }
    
    
    
    void UAS::setBattery(BatteryType type, int cells)
    {
        this->batteryType = type;
        this->cells = cells;
        switch (batteryType)
        {
    
    lm's avatar
    lm committed
        case NICD:
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case NIMH:
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case LIION:
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case LIPOLY:
    
    pixhawk's avatar
    pixhawk committed
            fullVoltage = this->cells * UAS::lipoFull;
            emptyVoltage = this->cells * UAS::lipoEmpty;
            break;
    
    lm's avatar
    lm committed
        case LIFE:
    
    pixhawk's avatar
    pixhawk committed
            break;
    
    lm's avatar
    lm committed
        case AGZN:
    
    pixhawk's avatar
    pixhawk committed
            break;
        }
    }
    
    
    void UAS::setBatterySpecs(const QString& specs)
    {
    
        if (specs.length() == 0 || specs.contains("%"))
    
            batteryRemainingEstimateEnabled = false;
    
            QString percent = specs;
            percent = percent.remove("%");
            float temp = percent.toFloat(&ok);
    
            if (ok)
            {
                warnLevelPercent = temp;
            }
            else
            {
                emit textMessageReceived(0, 0, 0, "Could not set battery options, format is wrong");
            }
    
        }
        else
        {
            batteryRemainingEstimateEnabled = true;
            QString stringList = specs;
            stringList = stringList.remove("V");
            stringList = stringList.remove("v");
            QStringList parts = stringList.split(",");
            if (parts.length() == 3)
            {
                float temp;
                bool ok;
                // Get the empty voltage
                temp = parts.at(0).toFloat(&ok);
                if (ok) emptyVoltage = temp;
                // Get the warning voltage
                temp = parts.at(1).toFloat(&ok);
                if (ok) warnVoltage = temp;
                // Get the full voltage
                temp = parts.at(2).toFloat(&ok);
                if (ok) fullVoltage = temp;
            }
    
            else
            {
                emit textMessageReceived(0, 0, 0, "Could not set battery options, format is wrong");
            }
    
        if (batteryRemainingEstimateEnabled)
        {
            return QString("%1V,%2V,%3V").arg(emptyVoltage).arg(warnVoltage).arg(fullVoltage);
        }
        else
        {
            return QString("%1%").arg(warnLevelPercent);
        }
    
    pixhawk's avatar
    pixhawk committed
    int UAS::calculateTimeRemaining()
    {
        quint64 dt = MG::TIME::getGroundTimeNow() - startTime;
        double seconds = dt / 1000.0f;
        double voltDifference = startVoltage - currentVoltage;
        if (voltDifference <= 0) voltDifference = 0.00000000001f;
        double dischargePerSecond = voltDifference / seconds;
        int remaining = static_cast<int>((currentVoltage - emptyVoltage) / dischargePerSecond);
        // Can never be below 0
        if (remaining < 0) remaining = 0;
        return remaining;
    }
    
    
    lm's avatar
    lm committed
    /**
     * @return charge level in percent - 0 - 100
     */
    
    float UAS::getChargeLevel()
    
    pixhawk's avatar
    pixhawk committed
    {
    
        if (batteryRemainingEstimateEnabled)
    
            if (lpVoltage < emptyVoltage)
            {
                chargeLevel = 0.0f;
            }
            else if (lpVoltage > fullVoltage)
            {
                chargeLevel = 100.0f;
            }
            else
            {