MAVLinkSimulationMAV.cc 11.5 KB
Newer Older
1
#include <QDebug>
2
#include <cmath>
pixhawk's avatar
pixhawk committed
3
#include <qmath.h>
4 5 6

#include "MAVLinkSimulationMAV.h"

7
MAVLinkSimulationMAV::MAVLinkSimulationMAV(MAVLinkSimulationLink *parent, int systemid, double lat, double lon, int version) :
8 9 10 11 12 13 14
        QObject(parent),
        link(parent),
        planner(parent, systemid),
        systemid(systemid),
        timer25Hz(0),
        timer10Hz(0),
        timer1Hz(0),
15 16
        latitude(lat),
        longitude(lon),
17
        altitude(0.0),
18 19
        x(lat),
        y(lon),
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
        z(550),
        roll(0.0),
        pitch(0.0),
        yaw(0.0),
        globalNavigation(true),
        firstWP(false),
        previousSPX(8.548056),
        previousSPY(47.376389),
        previousSPZ(550),
        previousSPYaw(0.0),
        nextSPX(8.548056),
        nextSPY(47.376389),
        nextSPZ(550),
        nextSPYaw(0.0),
        sys_mode(MAV_MODE_READY),
        sys_state(MAV_STATE_STANDBY),
        nav_mode(MAV_NAV_GROUNDED),
37 38
        flying(false),
        mavlink_version(version)
39
{
40
    // Please note: The waypoint planner is running
41
    connect(&mainloopTimer, SIGNAL(timeout()), this, SLOT(mainloop()));
42
    connect(&planner, SIGNAL(messageSent(mavlink_message_t)), this, SLOT(handleMessage(mavlink_message_t)));
43
    connect(link, SIGNAL(messageReceived(mavlink_message_t)), this, SLOT(handleMessage(mavlink_message_t)));
44
    mainloopTimer.start(20);
45 46 47 48 49
    mainloop();
}

void MAVLinkSimulationMAV::mainloop()
{
50
    // Calculate new simulator values
51
    //    double maxSpeed = 0.0001; // rad/s in earth coordinate frame
52

53
    //        double xNew = // (nextSPX - previousSPX)
54

55 56 57 58 59 60 61
    if (flying)
    {
        sys_state = MAV_STATE_ACTIVE;
        sys_mode = MAV_MODE_AUTO;
        nav_mode = MAV_NAV_WAYPOINT;
    }

62 63 64 65
    // 1 Hz execution
    if (timer1Hz <= 0)
    {
        mavlink_message_t msg;
66
        mavlink_msg_heartbeat_pack_version_free(systemid, MAV_COMP_ID_IMU, &msg, MAV_FIXED_WING, MAV_AUTOPILOT_PIXHAWK, mavlink_version);
67
        link->sendMAVLinkMessage(&msg);
pixhawk's avatar
pixhawk committed
68
        planner.handleMessage(msg);
69 70 71 72 73 74 75 76 77 78 79 80 81

        mavlink_servo_output_raw_t servos;
        servos.servo1_raw = 1000;
        servos.servo2_raw = 1250;
        servos.servo3_raw = 1400;
        servos.servo4_raw = 1500;
        servos.servo5_raw = 1800;
        servos.servo6_raw = 1500;
        servos.servo7_raw = 1500;
        servos.servo8_raw = 2000;

        mavlink_msg_servo_output_raw_encode(systemid, MAV_COMP_ID_IMU, &msg, &servos);
        link->sendMAVLinkMessage(&msg);
82 83 84 85 86 87
        timer1Hz = 50;
    }

    // 10 Hz execution
    if (timer10Hz <= 0)
    {
pixhawk's avatar
pixhawk committed
88 89 90 91 92
        double radPer100ms = 0.00006;
        double altPer100ms = 0.4;
        double xm = (nextSPX - x);
        double ym = (nextSPY - y);
        double zm = (nextSPZ - z);
pixhawk's avatar
pixhawk committed
93

pixhawk's avatar
pixhawk committed
94
        float zsign = (zm < 0) ? -1.0f : 1.0f;
pixhawk's avatar
pixhawk committed
95

pixhawk's avatar
pixhawk committed
96 97
        if (!firstWP)
        {
pixhawk's avatar
pixhawk committed
98 99
            //float trueyaw = atan2f(xm, ym);

100
            float newYaw = atan2f(ym, xm);
101 102 103 104 105 106

            if (fabs(yaw - newYaw) < 90)
            {
                yaw = yaw*0.7 + 0.3*newYaw;
            }
            else
pixhawk's avatar
pixhawk committed
107
            {
108 109 110 111 112 113 114 115
                yaw = newYaw;
            }

            //qDebug() << "SIMULATION MAV: x:" << xm << "y:" << ym << "z:" << zm << "yaw:" << yaw;

            //if (sqrt(xm*xm+ym*ym) > 0.0000001)
            if (flying)
            {
116 117
                x += cos(yaw)*radPer100ms;
                y += sin(yaw)*radPer100ms;
pixhawk's avatar
pixhawk committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
                z += altPer100ms*zsign;
            }

            //if (xm < 0.001) xm
        }
        else
        {
            x = nextSPX;
            y = nextSPY;
            z = nextSPZ;
            firstWP = false;
            qDebug() << "INIT STEP";
        }


133
        // GLOBAL POSITION
134 135 136
        mavlink_message_t msg;
        mavlink_global_position_int_t pos;
        pos.alt = z*1000.0;
137 138
        pos.lat = x*1E7;
        pos.lon = y*1E7;
139
        pos.vx = sin(yaw)*10.0f*100.0f;
lm's avatar
lm committed
140
        pos.vy = 0;
pixhawk's avatar
pixhawk committed
141
        pos.vz = altPer100ms*10.0f*100.0f*zsign*-1.0f;
142 143
        mavlink_msg_global_position_int_encode(systemid, MAV_COMP_ID_IMU, &msg, &pos);
        link->sendMAVLinkMessage(&msg);
pixhawk's avatar
pixhawk committed
144
        planner.handleMessage(msg);
145 146

        // ATTITUDE
pixhawk's avatar
pixhawk committed
147
        mavlink_attitude_t attitude;
148
        attitude.usec = 0;
pixhawk's avatar
pixhawk committed
149 150
        attitude.roll = 0.0f;
        attitude.pitch = 0.0f;
151
        attitude.yaw = yaw;
152 153 154
        attitude.rollspeed = 0.0f;
        attitude.pitchspeed = 0.0f;
        attitude.yawspeed = 0.0f;
pixhawk's avatar
pixhawk committed
155 156 157

        mavlink_msg_attitude_encode(systemid, MAV_COMP_ID_IMU, &msg, &attitude);
        link->sendMAVLinkMessage(&msg);
158 159 160 161 162 163 164 165 166

        // SYSTEM STATUS
        mavlink_sys_status_t status;
        status.load = 300;
        status.mode = sys_mode;
        status.nav_mode = nav_mode;
        status.packet_drop = 0;
        status.vbat = 10500;
        status.status = sys_state;
167
        status.battery_remaining = 912;
168
        mavlink_msg_sys_status_encode(systemid, MAV_COMP_ID_IMU, &msg, &status);
169
        link->sendMAVLinkMessage(&msg);
170
        timer10Hz = 5;
171 172 173

        // VFR HUD
        mavlink_vfr_hud_t hud;
174 175 176
        hud.airspeed = pos.vx/100.0f;
        hud.groundspeed = pos.vx/100.0f;
        hud.alt = z;
177
        hud.heading = static_cast<int>((yaw/M_PI)*180.0f+180.0f) % 360;
178
        hud.climb = pos.vz/100.0f;
179 180 181 182 183 184 185 186 187 188
        hud.throttle = 90;
        mavlink_msg_vfr_hud_encode(systemid, MAV_COMP_ID_IMU, &msg, &hud);
        link->sendMAVLinkMessage(&msg);

        // NAV CONTROLLER
        mavlink_nav_controller_output_t nav;
        nav.nav_roll = roll;
        nav.nav_pitch = pitch;
        nav.nav_bearing = yaw;
        nav.target_bearing = yaw;
lm's avatar
lm committed
189 190 191
        nav.wp_dist = 2.0f;
        nav.alt_error = 0.5f;
        nav.xtrack_error = 0.2f;
192
        nav.aspd_error = 0.0f;
193 194
        mavlink_msg_nav_controller_output_encode(systemid, MAV_COMP_ID_IMU, &msg, &nav);
        link->sendMAVLinkMessage(&msg);
195 196 197 198 199 200 201 202 203 204

        // RAW PRESSURE
        mavlink_raw_pressure_t pressure;
        pressure.press_abs = 1000;
        pressure.press_diff1 = 2000;
        pressure.press_diff2 = 5000;
        pressure.temperature = 18150; // 18.15 deg Celsius
        pressure.usec = 0; // Works also with zero timestamp
        mavlink_msg_raw_pressure_encode(systemid, MAV_COMP_ID_IMU, &msg, &pressure);
        link->sendMAVLinkMessage(&msg);
205 206 207 208 209
    }

    // 25 Hz execution
    if (timer25Hz <= 0)
    {
210 211 212
        // The message container to be used for sending
        mavlink_message_t ret;

James Goppert's avatar
James Goppert committed
213
        #ifdef MAVLINK_ENABLED_PIXHAWK
214 215 216 217 218 219
        // Send which controllers are active
        mavlink_control_status_t control_status;
        control_status.control_att = 1;
        control_status.control_pos_xy = 1;
        control_status.control_pos_yaw = 1;
        control_status.control_pos_z = 1;
220 221 222
        control_status.gps_fix = 2;        // 2D GPS fix
        control_status.position_fix = 3;   // 3D fix from GPS + barometric pressure
        control_status.vision_fix = 0;     // no fix from vision system
223
        control_status.ahrs_health = 230;
224 225
        mavlink_msg_control_status_encode(systemid, MAV_COMP_ID_IMU, &ret, &control_status);
        link->sendMAVLinkMessage(&ret);
James Goppert's avatar
James Goppert committed
226
        #endif //MAVLINK_ENABLED_PIXHAWK
227 228 229 230

        // Send actual controller outputs
        // This message just shows the direction
        // and magnitude of the control output
231 232 233 234 235 236
//        mavlink_position_controller_output_t pos;
//        pos.x = sin(yaw)*127.0f;
//        pos.y = cos(yaw)*127.0f;
//        pos.z = 0;
//        mavlink_msg_position_controller_output_encode(systemid, MAV_COMP_ID_IMU, &ret, &pos);
//        link->sendMAVLinkMessage(&ret);
pixhawk's avatar
pixhawk committed
237 238 239 240

        // Send a named value with name "FLOAT" and 0.5f as value

        // The message container to be used for sending
241
        //mavlink_message_t ret;
pixhawk's avatar
pixhawk committed
242 243 244 245 246 247 248
        // The C-struct holding the data to be sent
        mavlink_named_value_float_t val;

        // Fill in the data
        // Name of the value, maximum 10 characters
        // see full message specs at:
        // http://pixhawk.ethz.ch/wiki/mavlink/
Andrew Tridgell's avatar
Andrew Tridgell committed
249
        strcpy((char *)val.name, "FLOAT");
pixhawk's avatar
pixhawk committed
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
        // Value, in this case 0.5
        val.value = 0.5f;

        // Encode the data (adding header and checksums, etc.)
        mavlink_msg_named_value_float_encode(systemid, MAV_COMP_ID_IMU, &ret, &val);
        // And send it
        link->sendMAVLinkMessage(&ret);

        // MICROCONTROLLER SEND CODE:

        // uint8_t buf[MAVLINK_MAX_PACKET_LEN];
        // int16_t len = mavlink_msg_to_send_buffer(buf, &ret);
        // uart0_transmit(buf, len);


        // SEND INTEGER VALUE

        // We are reusing the "mavlink_message_t ret"
        // message buffer

        // The C-struct holding the data to be sent
        mavlink_named_value_int_t valint;

        // Fill in the data
        // Name of the value, maximum 10 characters
        // see full message specs at:
        // http://pixhawk.ethz.ch/wiki/mavlink/
Andrew Tridgell's avatar
Andrew Tridgell committed
277
        strcpy((char *)valint.name, "INTEGER");
pixhawk's avatar
pixhawk committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291
        // Value, in this case 18000
        valint.value = 18000;

        // Encode the data (adding header and checksums, etc.)
        mavlink_msg_named_value_int_encode(systemid, MAV_COMP_ID_IMU, &ret, &valint);
        // And send it
        link->sendMAVLinkMessage(&ret);

        // MICROCONTROLLER SEND CODE:

        // uint8_t buf[MAVLINK_MAX_PACKET_LEN];
        // int16_t len = mavlink_msg_to_send_buffer(buf, &ret);
        // uart0_transmit(buf, len);

292 293 294 295 296 297
        timer25Hz = 2;
    }

    timer1Hz--;
    timer10Hz--;
    timer25Hz--;
298 299 300 301
}

void MAVLinkSimulationMAV::handleMessage(const mavlink_message_t& msg)
{
302
    //qDebug() << "MAV:" << systemid << "RECEIVED MESSAGE FROM" << msg.sysid << "COMP" << msg.compid;
303 304 305 306 307

    switch(msg.msgid)
    {
    case MAVLINK_MSG_ID_ATTITUDE:
        break;
308 309 310 311 312 313 314 315 316 317 318 319 320
    case MAVLINK_MSG_ID_SET_MODE:
        {
            mavlink_set_mode_t mode;
            mavlink_msg_set_mode_decode(&msg, &mode);
            if (systemid == mode.target) sys_mode = mode.mode;
        }
        break;
    case MAVLINK_MSG_ID_ACTION:
        {
            mavlink_action_t action;
            mavlink_msg_action_decode(&msg, &action);
            if (systemid == action.target && (action.target_component == 0 || action.target_component == MAV_COMP_ID_IMU))
            {
lm's avatar
lm committed
321 322
                mavlink_action_ack_t ack;
                ack.action = action.action;
323 324
                switch (action.action)
                {
325
                case MAV_ACTION_TAKEOFF:
326
                    flying = true;
327
                    nav_mode = MAV_NAV_LIFTOFF;
lm's avatar
lm committed
328
                    ack.result = 1;
329 330 331
                    break;
                default:
                    {
lm's avatar
lm committed
332
                        ack.result = 0;
333 334 335
                    }
                    break;
                }
lm's avatar
lm committed
336 337 338 339 340

                // Give feedback about action
                mavlink_message_t r_msg;
                mavlink_msg_action_ack_encode(systemid, MAV_COMP_ID_IMU, &r_msg, &ack);
                link->sendMAVLinkMessage(&r_msg);
341 342 343
            }
        }
        break;
344 345 346 347 348 349
    case MAVLINK_MSG_ID_LOCAL_POSITION_SETPOINT_SET:
        {
            mavlink_local_position_setpoint_set_t sp;
            mavlink_msg_local_position_setpoint_set_decode(&msg, &sp);
            if (sp.target_system == this->systemid)
            {
350
                nav_mode = MAV_NAV_WAYPOINT;
351 352 353 354 355 356 357 358 359 360 361
                previousSPX = nextSPX;
                previousSPY = nextSPY;
                previousSPZ = nextSPZ;
                nextSPX = sp.x;
                nextSPY = sp.y;
                nextSPZ = sp.z;

                // Rotary wing
                //nextSPYaw = sp.yaw;

                // Airplane
pixhawk's avatar
pixhawk committed
362
                //yaw = atan2(previousSPX-nextSPX, previousSPY-nextSPY);
363

pixhawk's avatar
pixhawk committed
364
                //if (!firstWP) firstWP = true;
365 366 367 368
            }
            //qDebug() << "UPDATED SP:" << "X" << nextSPX << "Y" << nextSPY << "Z" << nextSPZ;
        }
        break;
369 370
    }
}