Skip to content
Snippets Groups Projects
UAS.cc 100 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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
    }
    
    
    /** 
    * @param rate The update rate in Hz the message should be sent
    
    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);
    //}
    
    /** 
    * @param rate The update rate in Hz the message should be sent
    
    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);
    }
    
    
    /** 
    * @param rate The update rate in Hz the message should be sent
    
    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);
    }
    
    
    /** 
    * @param rate The update rate in Hz the message should be sent
    
    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);
    }
    
    
    /** 
    * @param rate The update rate in Hz the message should be sent
    
    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 
    
    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 = MAV_PARAM_TYPE_INT32;
    
                break;
            case QVariant::UInt:
                union_value.param_uint32 = value.toUInt();
    
                p.param_type = MAV_PARAM_TYPE_UINT32;
    
                break;
            case QMetaType::Float:
                union_value.param_float = value.toFloat();
    
                p.param_type = MAV_PARAM_TYPE_REAL32;
    
                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;
    
    
            // 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
        }
    
    /**    
    * Request parameter, use parameter name to request it.
    
    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;
    
    * Request a parameter, use parameter name to request it.
    
    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;
    
    * @param systemType Type of MAV.
    
    void UAS::setSystemType(int systemType)
    {
    
        if((systemType >= MAV_TYPE_GENERIC) && (systemType < MAV_TYPE_ENUM_END))
    
          type = systemType;
        
          // If the airframe is still generic, change it to a close default type
          if (airframe == 0)
          {
              switch (systemType)
              {
              case MAV_TYPE_FIXED_WING:
                  airframe = QGC_AIRFRAME_EASYSTAR;
                  break;
              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;
    
    LM's avatar
    LM committed
        cmd.command = (uint16_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;
    
    LM's avatar
    LM committed
        cmd.command = (uint16_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
     *
    
    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
    }
    
    /**
    
    Lorenz Meier's avatar
    Lorenz Meier committed
     * @warning Depending on the UAS, this might make the rotors of a helicopter spinning
    
    pixhawk's avatar
    pixhawk committed
     *
    
    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 | MAV_MODE_FLAG_SAFETY_ARMED, navMode);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
    
    Lorenz Meier's avatar
    Lorenz Meier committed
     * @warning Depending on the UAS, this might completely stop all motors.
    
    pixhawk's avatar
    pixhawk committed
     *
    
    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 & ~MAV_MODE_FLAG_SAFETY_ARMED, navMode);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    /** 
    * Set the manual control commands. 
    
    * This can only be done if the system has manual inputs enabled and is armed.
    */
    
    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
    
    
    LM's avatar
    LM committed
            emit attitudeThrustSetPointChanged(this, roll, pitch, yaw, thrust, QGC::groundTimeMilliseconds());
    
            qDebug() << "JOYSTICK/MANUAL CONTROL: IGNORING COMMANDS: Set mode to MANUAL to send joystick commands first";
        }
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    /**
    * @return the type of the system
    
    /**
    * @param buttonIndex
    
    pixhawk's avatar
    pixhawk committed
    void UAS::receiveButton(int buttonIndex)
    {
    
    pixhawk's avatar
    pixhawk committed
        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!";
    
    * Halt the uas.
    
    pixhawk's avatar
    pixhawk committed
    void UAS::halt()
    {
    
        mavlink_message_t msg;
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_OVERRIDE_GOTO, 1, MAV_GOTO_DO_HOLD, MAV_GOTO_HOLD_AT_CURRENT_POSITION, 0, 0, 0, 0, 0);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    * Make the UAS move.
    
    pixhawk's avatar
    pixhawk committed
    void UAS::go()
    {
    
        mavlink_message_t msg;
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_OVERRIDE_GOTO, 1, MAV_GOTO_DO_CONTINUE, MAV_GOTO_HOLD_AT_CURRENT_POSITION, 0, 0, 0, 0, 0);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    /** 
    * Order the robot to return home 
    */
    
    pixhawk's avatar
    pixhawk committed
    void UAS::home()
    {
    
        mavlink_message_t msg;
    
        double latitude = UASManager::instance()->getHomeLatitude();
        double longitude = UASManager::instance()->getHomeLongitude();
        double altitude = UASManager::instance()->getHomeAltitude();
        int frame = UASManager::instance()->getHomeFrame();
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_OVERRIDE_GOTO, 1, MAV_GOTO_DO_CONTINUE, MAV_GOTO_HOLD_AT_CURRENT_POSITION, frame, 0, latitude, longitude, altitude);
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    /**
    * Order the robot to land on the runway 
    */
    
    void UAS::land()
    {
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_NAV_LAND, 1, 0, 0, 0, 0, 0, 0, 0);
        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()
    {
    
        // FIXME MAVLINKV10PORTINGNEEDED
        halt();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
    
     * Shut down this mav - All onboard systems are immediately shut down (e.g. the
     *  main power line is cut).
     * @warning This might lead to a crash.
    
    pixhawk's avatar
    pixhawk committed
     *
     * The command will not be executed until emergencyKILLConfirm is issues immediately afterwards
     */
    bool UAS::emergencyKILL()
    {
    
    lm's avatar
    lm committed
        // FIXME MAVLINKV10PORTINGNEEDED
    
    LM's avatar
    LM committed
        //    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;
        //        // 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);
        //        result = true;
        //    }
        //    return result;
    
    lm's avatar
    lm committed
        return false;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    * If enabled, connect the fligth gear link. 
    
    lm's avatar
    lm committed
    void UAS::enableHil(bool enable)
    {
        // Connect Flight Gear Link
        if (enable)
        {
    
            startHil();
    
    lm's avatar
    lm committed
        }
        else
        {
    
            stopHil();
    
    lm's avatar
    lm committed
        }
    }
    
    /**
    * @param time_us Timestamp (microseconds since UNIX epoch or microseconds since system boot)
    * @param roll Roll angle (rad)
    * @param pitch Pitch angle (rad)
    * @param yaw Yaw angle (rad)
    * @param rollspeed Roll angular speed (rad/s)
    * @param pitchspeed Pitch angular speed (rad/s)
    * @param yawspeed Yaw angular speed (rad/s)
    * @param lat Latitude, expressed as * 1E7
    * @param lon Longitude, expressed as * 1E7
    * @param alt Altitude in meters, expressed as * 1000 (millimeters)
    * @param vx Ground X Speed (Latitude), expressed as m/s * 100
    * @param vy Ground Y Speed (Longitude), expressed as m/s * 100
    * @param vz Ground Z Speed (Altitude), expressed as m/s * 100
    * @param xacc X acceleration (mg)
    * @param yacc Y acceleration (mg)
    * @param zacc Z acceleration (mg)
    */
    void UAS::sendHilState(uint64_t time_us, float roll, float pitch, float yaw, float rollspeed,
    
    LM's avatar
    LM committed
                           float pitchspeed, float yawspeed, int32_t lat, int32_t lon, int32_t alt,
                           int16_t vx, int16_t vy, int16_t vz, int16_t xacc, int16_t yacc, int16_t zacc)
    
    lm's avatar
    lm committed
    {
    
        if (this->mode & MAV_MODE_FLAG_HIL_ENABLED)
        {
            mavlink_message_t msg;
            mavlink_msg_hil_state_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, time_us, roll, pitch, yaw, rollspeed, pitchspeed, yawspeed, lat, lon, alt, vx, vy, vz, xacc, yacc, zacc);
            sendMessage(msg);
        }
        else
        {
            // Attempt to set HIL mode
            mavlink_message_t msg;
            mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode);
            sendMessage(msg);
            qDebug() << __FILE__ << __LINE__ << "HIL is onboard not enabled, trying to enable.";
        }
    
    lm's avatar
    lm committed
    }
    
    
    * Connect flight gear link.
    
    void UAS::startHil()
    {
    
    lm's avatar
    lm committed
        // Connect Flight Gear Link
        simulation->connectSimulation();
    
        mavlink_message_t msg;
    
    LM's avatar
    LM committed
        mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode | MAV_MODE_FLAG_HIL_ENABLED, navMode);
    
        sendMessage(msg);
    
    * disable flight gear link.
    
    void UAS::stopHil()
    {
    
    lm's avatar
    lm committed
        simulation->disconnectSimulation();
    
        mavlink_message_t msg;
    
    LM's avatar
    LM committed
        mavlink_msg_set_mode_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), mode & !MAV_MODE_FLAG_HIL_ENABLED, navMode);
    
        sendMessage(msg);
    
    pixhawk's avatar
    pixhawk committed
    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?");
    
    lm's avatar
    lm committed
    
    
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Cancel);
        int ret = msgBox.exec();
    
    lm's avatar
    lm committed
    
    
        // Close the message box shortly after the click to prevent accidental clicks
        QTimer::singleShot(5000, &msgBox, SLOT(reject()));
    
    lm's avatar
    lm committed
    
    
        if (ret == QMessageBox::Yes)
        {
            // If the active UAS is set, execute command
            mavlink_message_t msg;
    
    pixhawk's avatar
    pixhawk committed
            mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 0, 2, 0, 0, 0, 0, 0);
    
            sendMessage(msg);
            result = true;
        }
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    * @param x position
    * @param y position
    * @param z position
    
    * @param yaw
    
    void UAS::setTargetPosition(float x, float y, float z, float yaw)
    {
    
        mavlink_message_t msg;
    
        mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_NAV_PATHPLANNING, 1, 1, 1, 0, yaw, x, y, z);
    
        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;
    
    pixhawk's avatar
    pixhawk committed
            result = tr("MAV ") + result.sprintf("%03d", getUASID());
    
    pixhawk's avatar
    pixhawk committed
            result = name;
        }
        return result;
    }
    
    
    /**
    * @return the state of the uas as a short text.
    
    const QString& UAS::getShortState() const
    {
        return shortStateText;
    }
    
    
    * The mode can be autonomous, guided, manual or armed. It will also return if 
    * hardware in the loop is being used.
    
    * @return the audio mode text for the id given.
    
    QString UAS::getAudioModeTextFor(int id)
    {
        QString mode;
        uint8_t modeid = id;
    
        // BASE MODE DECODING
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_AUTO)
        {
            mode += "autonomous";
        }
        else if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_GUIDED)
        {
            mode += "guided";
        }
        else if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_MANUAL)
        {
            mode += "manual";
        }
    
        else
        {
            // Nothing else applies, we're in preflight
            mode += "preflight";
        }
    
    
        if (modeid != 0)
        {
            mode += " mode";
        }
    
        // ARMED STATE DECODING
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_SAFETY)
        {
            mode.append(" and armed");
        }
    
        // HARDWARE IN THE LOOP DECODING
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_HIL)
        {
            mode.append(" using hardware in the loop simulation");
        }
    
        return mode;
    }
    
    
    * The mode returned can be auto, stabilized, test, manual, preflight or unknown. 
    
    * @return the short text of the mode for the id given.
    
    QString UAS::getShortModeTextFor(int id)
    {
        QString mode;
    
    LM's avatar
    LM committed
        uint8_t modeid = id;
    
        qDebug() << "MODE:" << modeid;
    
    LM's avatar
    LM committed
        // BASE MODE DECODING
    
    pixhawk's avatar
    pixhawk committed
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_AUTO)
    
    LM's avatar
    LM committed
        {
    
    pixhawk's avatar
    pixhawk committed
            mode += "AUTO";
    
    LM's avatar
    LM committed
        }
    
        else if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_GUIDED)
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
    
    //    if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_STABILIZE)
    //    {
    //        mode += "|STAB";
    //    }
        else if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_TEST)
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
    
        else if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_MANUAL)
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
    
        // ARMED STATE DECODING
    
    pixhawk's avatar
    pixhawk committed
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_SAFETY)
    
    LM's avatar
    LM committed
        {
    
    LM's avatar
    LM committed
        }
        else
        {
    
    LM's avatar
    LM committed
        }
    
        // HARDWARE IN THE LOOP DECODING
    
    pixhawk's avatar
    pixhawk committed
        if (modeid & (uint8_t)MAV_MODE_FLAG_DECODE_POSITION_HIL)
    
    LM's avatar
    LM committed
        {
            mode.prepend("HIL:");
    
    const QString& UAS::getShortMode() const
    {
        return shortModeText;
    }
    
    
    * Add the link and connect a signal to it which will be set off when it is destroyed.
    
    pixhawk's avatar
    pixhawk committed
    void UAS::addLink(LinkInterface* link)
    {
    
    pixhawk's avatar
    pixhawk committed
            links->append(link);
    
            connect(link, SIGNAL(destroyed(QObject*)), this, SLOT(removeLink(QObject*)));
    
    pixhawk's avatar
    pixhawk committed
        }
    }
    
    
    void UAS::removeLink(QObject* object)
    {
        LinkInterface* link = dynamic_cast<LinkInterface*>(object);
    
            links->removeAt(links->indexOf(link));
        }
    }
    
    
    /**
    * @return the list of links
    
    pixhawk's avatar
    pixhawk committed
    QList<LinkInterface*>* UAS::getLinks()
    {
        return links;
    }
    
    
    /**
    * @rerturn the map of the components
    
    LM's avatar
    LM committed
    QMap<int, QString> UAS::getComponents()
    {
        return components;
    }
    
    
    * Set the battery type and the  number of cells.
    
    * @param type of the battery
    
    * @param cells Number of cells.
    
    pixhawk's avatar
    pixhawk committed
    void UAS::setBattery(BatteryType type, int cells)
    {
        this->batteryType = type;
        this->cells = cells;
    
    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;
        }
    }
    
    
    * Set the battery specificaitons: empty voltage, warning voltage, and full voltage.
    
    * @param specifications of the battery
    
    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);
    
                warnLevelPercent = temp;
    
                emit textMessageReceived(0, 0, 0, "Could not set battery options, format is wrong");
            }
    
            batteryRemainingEstimateEnabled = true;
            QString stringList = specs;
            stringList = stringList.remove("V");
            stringList = stringList.remove("v");
            QStringList parts = stringList.split(",");
    
                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;
    
                emit textMessageReceived(0, 0, 0, "Could not set battery options, format is wrong");
            }
    
    * @return the battery specifications(empty voltage, warning voltage, full voltage)
    */
    
            return QString("%1V,%2V,%3V").arg(emptyVoltage).arg(warnVoltage).arg(fullVoltage);
    
            return QString("%1%").arg(warnLevelPercent);
        }
    
    /**
    * @return the time remaining.
    
    pixhawk's avatar
    pixhawk committed
    int UAS::calculateTimeRemaining()
    {
    
    LM's avatar
    LM committed
        quint64 dt = QGC::groundTimeMilliseconds() - startTime;
    
    pixhawk's avatar
    pixhawk committed
        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;
    
                chargeLevel = 100.0f;
    
                chargeLevel = 100.0f * ((lpVoltage - emptyVoltage)/(fullVoltage - emptyVoltage));
            }
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    lm's avatar
    lm committed
    void UAS::startLowBattAlarm()
    {
    
            GAudioOutput::instance()->alert(tr("system %1 has low battery").arg(getUASName()));
    
            QTimer::singleShot(3000, GAudioOutput::instance(), SLOT(startEmergency()));
    
    lm's avatar
    lm committed
            lowBattAlarm = true;
        }
    }
    
    void UAS::stopLowBattAlarm()
    {
    
    lm's avatar
    lm committed
            GAudioOutput::instance()->stopEmergency();
            lowBattAlarm = false;
        }
    }