void GCS_Mavlink<T>::handle_command_long(mavlink_message_t *msg) { mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); Serial.print("command:");Serial.println(packet.command); Serial.print("target_system:");Serial.println(packet.target_system); Serial.print("target_component:");Serial.println(packet.target_component); Serial.print("param1:");Serial.println(packet.param1); Serial.print("param2:");Serial.println(packet.param2); Serial.print("param3:");Serial.println(packet.param3); Serial.print("param4:");Serial.println(packet.param4); Serial.print("param5:");Serial.println(packet.param5); Serial.print("param6:");Serial.println(packet.param6); Serial.print("param7:");Serial.println(packet.param7); switch(packet.command) { case MAV_CMD_NAV_TAKEOFF:{ break; } case MAV_CMD_COMPONENT_ARM_DISARM:{ if(packet.param1==1){ motorsQuad.set_armed(ARM); leds.set_state(R, ON); arm_mav_mode(); }else{ motorsQuad.set_armed(DISARM); leds.set_state(R, OFF); disarm_mav_mode(); } } } }
void GCS_Mavlink<T>::handle_command_long(mavlink_message_t *msg) { mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); Serial.print("command:"); Serial.println(packet.command); Serial.print("target_system:"); Serial.println(packet.target_system); Serial.print("target_component:"); Serial.println(packet.target_component); Serial.print("param1:"); Serial.println(packet.param1); Serial.print("param2:"); Serial.println(packet.param2); Serial.print("param3:"); Serial.println(packet.param3); Serial.print("param4:"); Serial.println(packet.param4); Serial.print("param5:"); Serial.println(packet.param5); Serial.print("param6:"); Serial.println(packet.param6); Serial.print("param7:"); Serial.println(packet.param7); switch (packet.command) { case MAV_CMD_NAV_TAKEOFF: { break; } } }
void MavlinkReceiver::handle_message_command_long(mavlink_message_t *msg) { /* command */ mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) || (cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { //check for MAVLINK terminate command if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && ((int)cmd_mavlink.param1) == 3) { /* This is the link shutdown command, terminate mavlink */ warnx("terminated by remote command"); fflush(stdout); usleep(50000); /* terminate other threads and this thread */ _mavlink->_task_should_exit = true; } else { struct vehicle_command_s vcmd; memset(&vcmd, 0, sizeof(vcmd)); /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = cmd_mavlink.param1; vcmd.param2 = cmd_mavlink.param2; vcmd.param3 = cmd_mavlink.param3; vcmd.param4 = cmd_mavlink.param4; vcmd.param5 = cmd_mavlink.param5; vcmd.param6 = cmd_mavlink.param6; vcmd.param7 = cmd_mavlink.param7; // XXX do proper translation vcmd.command = (enum VEHICLE_CMD)cmd_mavlink.command; vcmd.target_system = cmd_mavlink.target_system; vcmd.target_component = cmd_mavlink.target_component; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = cmd_mavlink.confirmation; if (_cmd_pub < 0) { _cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } else { orb_publish(ORB_ID(vehicle_command), _cmd_pub, &vcmd); } } } }
void mission_command(void) { mavlink_command_long_t mmcl; mavlink_msg_command_long_decode(&received_msg, &mmcl); switch(mmcl.command) { case MAV_CMD_DO_SET_MODE: break; case MAV_CMD_DO_JUMP: break; case MAV_CMD_DO_CHANGE_SPEED: break; case MAV_CMD_DO_SET_HOME: waypoint_info.home_waypoint.latitude = mmcl.param5; waypoint_info.home_waypoint.longitude = mmcl.param6; waypoint_info.home_waypoint.altitude = mmcl.param7; waypoint_info.home_waypoint.use_current = (int)mmcl.param1; waypoint_info.home_waypoint.is_set = true; break; case MAV_CMD_OVERRIDE_GOTO: waypoint_info.mission_status = (int)mmcl.param1; waypoint_info.hold_waypoint.latitude = mmcl.param5; waypoint_info.hold_waypoint.longitude = mmcl.param6; waypoint_info.hold_waypoint.altitude = mmcl.param7; waypoint_info.hold_waypoint.coordinate_frame = (int)mmcl.param3; waypoint_info.hold_waypoint.yaw_angle = mmcl.param4; waypoint_info.hold_waypoint.hold_waypoint = (int)mmcl.param2; waypoint_info.hold_waypoint.is_set = true; break; case MAV_CMD_MISSION_START: break; case MAV_CMD_COMPONENT_ARM_DISARM: break; default: break; } }
void mavlink_connector::handle_command_long(mavlink_message_t *msg) { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(msg,&cmd); switch(cmd.command) { case MAV_CMD_NAV_TAKEOFF: dji_commands::set_takeoff(); printf("recv takeof..\n"); break; case MAV_CMD_NAV_LAND: dji_commands::set_land(); printf("land mode..\n"); break; case MAV_CMD_NAV_RETURN_TO_LAUNCH: dji_commands::set_return2home(); printf("return to home\n"); break; default: printf("cmd is %d\n",cmd.command); } }
static void handle_message(mavlink_message_t *msg) { if (msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) || (cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { //check for MAVLINK terminate command if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && ((int)cmd_mavlink.param1) == 3) { /* This is the link shutdown command, terminate mavlink */ printf("[mavlink] Terminating .. \n"); fflush(stdout); usleep(50000); /* terminate other threads and this thread */ thread_should_exit = true; } else { /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = cmd_mavlink.param1; vcmd.param2 = cmd_mavlink.param2; vcmd.param3 = cmd_mavlink.param3; vcmd.param4 = cmd_mavlink.param4; vcmd.param5 = cmd_mavlink.param5; vcmd.param6 = cmd_mavlink.param6; vcmd.param7 = cmd_mavlink.param7; // XXX do proper translation vcmd.command = (enum VEHICLE_CMD)cmd_mavlink.command; vcmd.target_system = cmd_mavlink.target_system; vcmd.target_component = cmd_mavlink.target_component; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = cmd_mavlink.confirmation; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } else { /* publish */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } } } if (msg->msgid == MAVLINK_MSG_ID_OPTICAL_FLOW) { mavlink_optical_flow_t flow; mavlink_msg_optical_flow_decode(msg, &flow); struct optical_flow_s f; f.timestamp = flow.time_usec; f.flow_raw_x = flow.flow_x; f.flow_raw_y = flow.flow_y; f.flow_comp_x_m = flow.flow_comp_m_x; f.flow_comp_y_m = flow.flow_comp_m_y; f.ground_distance_m = flow.ground_distance; f.quality = flow.quality; f.sensor_id = flow.sensor_id; /* check if topic is advertised */ if (flow_pub <= 0) { flow_pub = orb_advertise(ORB_ID(optical_flow), &f); } else { /* publish */ orb_publish(ORB_ID(optical_flow), flow_pub, &f); } } if (msg->msgid == MAVLINK_MSG_ID_SET_MODE) { /* Set mode on request */ mavlink_set_mode_t new_mode; mavlink_msg_set_mode_decode(msg, &new_mode); union px4_custom_mode custom_mode; custom_mode.data = new_mode.custom_mode; /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = new_mode.base_mode; vcmd.param2 = custom_mode.main_mode; vcmd.param3 = 0; vcmd.param4 = 0; vcmd.param5 = 0; vcmd.param6 = 0; vcmd.param7 = 0; vcmd.command = VEHICLE_CMD_DO_SET_MODE; vcmd.target_system = new_mode.target_system; vcmd.target_component = MAV_COMP_ID_ALL; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = 1; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } else { /* create command */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } /* Handle Vicon position estimates */ if (msg->msgid == MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE) { mavlink_vicon_position_estimate_t pos; mavlink_msg_vicon_position_estimate_decode(msg, &pos); vicon_position.timestamp = hrt_absolute_time(); vicon_position.x = pos.x; vicon_position.y = pos.y; vicon_position.z = pos.z; vicon_position.roll = pos.roll; vicon_position.pitch = pos.pitch; vicon_position.yaw = pos.yaw; if (vicon_position_pub <= 0) { vicon_position_pub = orb_advertise(ORB_ID(vehicle_vicon_position), &vicon_position); } else { orb_publish(ORB_ID(vehicle_vicon_position), vicon_position_pub, &vicon_position); } } /* Handle quadrotor motor setpoints */ if (msg->msgid == MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST) { mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t quad_motors_setpoint; mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(msg, &quad_motors_setpoint); if (mavlink_system.sysid < 4) { /* switch to a receiving link mode */ gcs_link = false; /* * rate control mode - defined by MAVLink */ uint8_t ml_mode = 0; bool ml_armed = false; switch (quad_motors_setpoint.mode) { case 0: ml_armed = false; break; case 1: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_RATES; ml_armed = true; break; case 2: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_ATTITUDE; ml_armed = true; break; case 3: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_VELOCITY; break; case 4: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_POSITION; break; } offboard_control_sp.p1 = (float)quad_motors_setpoint.roll[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p2 = (float)quad_motors_setpoint.pitch[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p3 = (float)quad_motors_setpoint.yaw[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p4 = (float)quad_motors_setpoint.thrust[mavlink_system.sysid - 1] / (float)UINT16_MAX; if (quad_motors_setpoint.thrust[mavlink_system.sysid - 1] == 0) { ml_armed = false; } offboard_control_sp.armed = ml_armed; offboard_control_sp.mode = static_cast<enum OFFBOARD_CONTROL_MODE>(ml_mode); offboard_control_sp.timestamp = hrt_absolute_time(); /* check if topic has to be advertised */ if (offboard_control_sp_pub <= 0) { offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); } else { /* Publish */ orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); } } } /* handle status updates of the radio */ if (msg->msgid == MAVLINK_MSG_ID_RADIO_STATUS) { struct telemetry_status_s tstatus; mavlink_radio_status_t rstatus; mavlink_msg_radio_status_decode(msg, &rstatus); /* publish telemetry status topic */ tstatus.timestamp = hrt_absolute_time(); tstatus.type = TELEMETRY_STATUS_RADIO_TYPE_3DR_RADIO; tstatus.rssi = rstatus.rssi; tstatus.remote_rssi = rstatus.remrssi; tstatus.txbuf = rstatus.txbuf; tstatus.noise = rstatus.noise; tstatus.remote_noise = rstatus.remnoise; tstatus.rxerrors = rstatus.rxerrors; tstatus.fixed = rstatus.fixed; if (telemetry_status_pub == 0) { telemetry_status_pub = orb_advertise(ORB_ID(telemetry_status), &tstatus); } else { orb_publish(ORB_ID(telemetry_status), telemetry_status_pub, &tstatus); } } /* * Only decode hil messages in HIL mode. * * The HIL mode is enabled by the HIL bit flag * in the system mode. Either send a set mode * COMMAND_LONG message or a SET_MODE message */ if (mavlink_hil_enabled) { uint64_t timestamp = hrt_absolute_time(); if (msg->msgid == MAVLINK_MSG_ID_HIL_SENSOR) { mavlink_hil_sensor_t imu; mavlink_msg_hil_sensor_decode(msg, &imu); /* sensors general */ hil_sensors.timestamp = hrt_absolute_time(); /* hil gyro */ static const float mrad2rad = 1.0e-3f; hil_sensors.gyro_counter = hil_counter; hil_sensors.gyro_raw[0] = imu.xgyro / mrad2rad; hil_sensors.gyro_raw[1] = imu.ygyro / mrad2rad; hil_sensors.gyro_raw[2] = imu.zgyro / mrad2rad; hil_sensors.gyro_rad_s[0] = imu.xgyro; hil_sensors.gyro_rad_s[1] = imu.ygyro; hil_sensors.gyro_rad_s[2] = imu.zgyro; /* accelerometer */ hil_sensors.accelerometer_counter = hil_counter; static const float mg2ms2 = 9.8f / 1000.0f; hil_sensors.accelerometer_raw[0] = imu.xacc / mg2ms2; hil_sensors.accelerometer_raw[1] = imu.yacc / mg2ms2; hil_sensors.accelerometer_raw[2] = imu.zacc / mg2ms2; hil_sensors.accelerometer_m_s2[0] = imu.xacc; hil_sensors.accelerometer_m_s2[1] = imu.yacc; hil_sensors.accelerometer_m_s2[2] = imu.zacc; hil_sensors.accelerometer_mode = 0; // TODO what is this? hil_sensors.accelerometer_range_m_s2 = 32.7f; // int16 /* adc */ hil_sensors.adc_voltage_v[0] = 0.0f; hil_sensors.adc_voltage_v[1] = 0.0f; hil_sensors.adc_voltage_v[2] = 0.0f; /* magnetometer */ float mga2ga = 1.0e-3f; hil_sensors.magnetometer_counter = hil_counter; hil_sensors.magnetometer_raw[0] = imu.xmag / mga2ga; hil_sensors.magnetometer_raw[1] = imu.ymag / mga2ga; hil_sensors.magnetometer_raw[2] = imu.zmag / mga2ga; hil_sensors.magnetometer_ga[0] = imu.xmag; hil_sensors.magnetometer_ga[1] = imu.ymag; hil_sensors.magnetometer_ga[2] = imu.zmag; hil_sensors.magnetometer_range_ga = 32.7f; // int16 hil_sensors.magnetometer_mode = 0; // TODO what is this hil_sensors.magnetometer_cuttoff_freq_hz = 50.0f; /* baro */ hil_sensors.baro_pres_mbar = imu.abs_pressure; hil_sensors.baro_alt_meter = imu.pressure_alt; hil_sensors.baro_temp_celcius = imu.temperature; hil_sensors.gyro_counter = hil_counter; hil_sensors.magnetometer_counter = hil_counter; hil_sensors.accelerometer_counter = hil_counter; /* differential pressure */ hil_sensors.differential_pressure_pa = imu.diff_pressure * 1e2f; //from hPa to Pa hil_sensors.differential_pressure_counter = hil_counter; /* airspeed from differential pressure, ambient pressure and temp */ struct airspeed_s airspeed; float ias = calc_indicated_airspeed(hil_sensors.differential_pressure_pa); // XXX need to fix this float tas = ias; airspeed.timestamp = hrt_absolute_time(); airspeed.indicated_airspeed_m_s = ias; airspeed.true_airspeed_m_s = tas; if (pub_hil_airspeed < 0) { pub_hil_airspeed = orb_advertise(ORB_ID(airspeed), &airspeed); } else { orb_publish(ORB_ID(airspeed), pub_hil_airspeed, &airspeed); } //warnx("SENSOR: IAS: %6.2f TAS: %6.2f", airspeed.indicated_airspeed_m_s, airspeed.true_airspeed_m_s); /* individual sensor publications */ struct gyro_report gyro; gyro.x_raw = imu.xgyro / mrad2rad; gyro.y_raw = imu.ygyro / mrad2rad; gyro.z_raw = imu.zgyro / mrad2rad; gyro.x = imu.xgyro; gyro.y = imu.ygyro; gyro.z = imu.zgyro; gyro.temperature = imu.temperature; gyro.timestamp = hrt_absolute_time(); if (pub_hil_gyro < 0) { pub_hil_gyro = orb_advertise(ORB_ID(sensor_gyro), &gyro); } else { orb_publish(ORB_ID(sensor_gyro), pub_hil_gyro, &gyro); } struct accel_report accel; accel.x_raw = imu.xacc / mg2ms2; accel.y_raw = imu.yacc / mg2ms2; accel.z_raw = imu.zacc / mg2ms2; accel.x = imu.xacc; accel.y = imu.yacc; accel.z = imu.zacc; accel.temperature = imu.temperature; accel.timestamp = hrt_absolute_time(); if (pub_hil_accel < 0) { pub_hil_accel = orb_advertise(ORB_ID(sensor_accel), &accel); } else { orb_publish(ORB_ID(sensor_accel), pub_hil_accel, &accel); } struct mag_report mag; mag.x_raw = imu.xmag / mga2ga; mag.y_raw = imu.ymag / mga2ga; mag.z_raw = imu.zmag / mga2ga; mag.x = imu.xmag; mag.y = imu.ymag; mag.z = imu.zmag; mag.timestamp = hrt_absolute_time(); if (pub_hil_mag < 0) { pub_hil_mag = orb_advertise(ORB_ID(sensor_mag), &mag); } else { orb_publish(ORB_ID(sensor_mag), pub_hil_mag, &mag); } struct baro_report baro; baro.pressure = imu.abs_pressure; baro.altitude = imu.pressure_alt; baro.temperature = imu.temperature; baro.timestamp = hrt_absolute_time(); if (pub_hil_baro < 0) { pub_hil_baro = orb_advertise(ORB_ID(sensor_baro), &baro); } else { orb_publish(ORB_ID(sensor_baro), pub_hil_baro, &baro); } /* publish combined sensor topic */ if (pub_hil_sensors > 0) { orb_publish(ORB_ID(sensor_combined), pub_hil_sensors, &hil_sensors); } else { pub_hil_sensors = orb_advertise(ORB_ID(sensor_combined), &hil_sensors); } /* fill in HIL battery status */ hil_battery_status.timestamp = hrt_absolute_time(); hil_battery_status.voltage_v = 11.1f; hil_battery_status.current_a = 10.0f; /* lazily publish the battery voltage */ if (pub_hil_battery > 0) { orb_publish(ORB_ID(battery_status), pub_hil_battery, &hil_battery_status); } else { pub_hil_battery = orb_advertise(ORB_ID(battery_status), &hil_battery_status); } // increment counters hil_counter++; hil_frames++; // output if ((timestamp - old_timestamp) > 10000000) { printf("receiving hil sensor at %d hz\n", hil_frames / 10); old_timestamp = timestamp; hil_frames = 0; } } if (msg->msgid == MAVLINK_MSG_ID_HIL_GPS) { mavlink_hil_gps_t gps; mavlink_msg_hil_gps_decode(msg, &gps); /* gps */ hil_gps.timestamp_position = gps.time_usec; hil_gps.time_gps_usec = gps.time_usec; hil_gps.lat = gps.lat; hil_gps.lon = gps.lon; hil_gps.alt = gps.alt; hil_gps.eph_m = (float)gps.eph * 1e-2f; // from cm to m hil_gps.epv_m = (float)gps.epv * 1e-2f; // from cm to m hil_gps.s_variance_m_s = 5.0f; hil_gps.p_variance_m = hil_gps.eph_m * hil_gps.eph_m; hil_gps.vel_m_s = (float)gps.vel * 1e-2f; // from cm/s to m/s /* gps.cog is in degrees 0..360 * 100, heading is -PI..+PI */ float heading_rad = gps.cog * M_DEG_TO_RAD_F * 1e-2f; /* go back to -PI..PI */ if (heading_rad > M_PI_F) heading_rad -= 2.0f * M_PI_F; hil_gps.vel_n_m_s = gps.vn * 1e-2f; // from cm to m hil_gps.vel_e_m_s = gps.ve * 1e-2f; // from cm to m hil_gps.vel_d_m_s = gps.vd * 1e-2f; // from cm to m hil_gps.vel_ned_valid = true; /* COG (course over ground) is spec'ed as -PI..+PI */ hil_gps.cog_rad = heading_rad; hil_gps.fix_type = gps.fix_type; hil_gps.satellites_visible = gps.satellites_visible; /* publish GPS measurement data */ if (pub_hil_gps > 0) { orb_publish(ORB_ID(vehicle_gps_position), pub_hil_gps, &hil_gps); } else { pub_hil_gps = orb_advertise(ORB_ID(vehicle_gps_position), &hil_gps); } } if (msg->msgid == MAVLINK_MSG_ID_HIL_STATE_QUATERNION) { mavlink_hil_state_quaternion_t hil_state; mavlink_msg_hil_state_quaternion_decode(msg, &hil_state); struct airspeed_s airspeed; airspeed.timestamp = hrt_absolute_time(); airspeed.indicated_airspeed_m_s = hil_state.ind_airspeed * 1e-2f; airspeed.true_airspeed_m_s = hil_state.true_airspeed * 1e-2f; if (pub_hil_airspeed < 0) { pub_hil_airspeed = orb_advertise(ORB_ID(airspeed), &airspeed); } else { orb_publish(ORB_ID(airspeed), pub_hil_airspeed, &airspeed); } uint64_t timestamp = hrt_absolute_time(); // publish global position if (pub_hil_global_pos > 0) { orb_publish(ORB_ID(vehicle_global_position), pub_hil_global_pos, &hil_global_pos); // global position packet hil_global_pos.timestamp = timestamp; hil_global_pos.valid = true; hil_global_pos.lat = hil_state.lat; hil_global_pos.lon = hil_state.lon; hil_global_pos.alt = hil_state.alt / 1000.0f; hil_global_pos.vx = hil_state.vx / 100.0f; hil_global_pos.vy = hil_state.vy / 100.0f; hil_global_pos.vz = hil_state.vz / 100.0f; } else { pub_hil_global_pos = orb_advertise(ORB_ID(vehicle_global_position), &hil_global_pos); } // publish local position if (pub_hil_local_pos > 0) { float x; float y; bool landed = hil_state.alt/1000.0f < (alt0 + 0.1); // XXX improve? double lat = hil_state.lat*1e-7; double lon = hil_state.lon*1e-7; map_projection_project(lat, lon, &x, &y); hil_local_pos.timestamp = timestamp; hil_local_pos.xy_valid = true; hil_local_pos.z_valid = true; hil_local_pos.v_xy_valid = true; hil_local_pos.v_z_valid = true; hil_local_pos.x = x; hil_local_pos.y = y; hil_local_pos.z = alt0 - hil_state.alt/1000.0f; hil_local_pos.vx = hil_state.vx/100.0f; hil_local_pos.vy = hil_state.vy/100.0f; hil_local_pos.vz = hil_state.vz/100.0f; hil_local_pos.yaw = hil_attitude.yaw; hil_local_pos.xy_global = true; hil_local_pos.z_global = true; hil_local_pos.ref_timestamp = timestamp; hil_local_pos.ref_lat = hil_state.lat; hil_local_pos.ref_lon = hil_state.lon; hil_local_pos.ref_alt = alt0; hil_local_pos.landed = landed; orb_publish(ORB_ID(vehicle_local_position), pub_hil_local_pos, &hil_local_pos); } else { pub_hil_local_pos = orb_advertise(ORB_ID(vehicle_local_position), &hil_local_pos); lat0 = hil_state.lat; lon0 = hil_state.lon; alt0 = hil_state.alt / 1000.0f; map_projection_init(hil_state.lat, hil_state.lon); } /* Calculate Rotation Matrix */ math::Quaternion q(hil_state.attitude_quaternion); math::Dcm C_nb(q); math::EulerAngles euler(C_nb); /* set rotation matrix */ for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) hil_attitude.R[i][j] = C_nb(i, j); hil_attitude.R_valid = true; /* set quaternion */ hil_attitude.q[0] = q(0); hil_attitude.q[1] = q(1); hil_attitude.q[2] = q(2); hil_attitude.q[3] = q(3); hil_attitude.q_valid = true; hil_attitude.roll = euler.getPhi(); hil_attitude.pitch = euler.getTheta(); hil_attitude.yaw = euler.getPsi(); hil_attitude.rollspeed = hil_state.rollspeed; hil_attitude.pitchspeed = hil_state.pitchspeed; hil_attitude.yawspeed = hil_state.yawspeed; /* set timestamp and notify processes (broadcast) */ hil_attitude.timestamp = hrt_absolute_time(); if (pub_hil_attitude > 0) { orb_publish(ORB_ID(vehicle_attitude), pub_hil_attitude, &hil_attitude); } else { pub_hil_attitude = orb_advertise(ORB_ID(vehicle_attitude), &hil_attitude); } struct accel_report accel; accel.x_raw = hil_state.xacc / 9.81f * 1e3f; accel.y_raw = hil_state.yacc / 9.81f * 1e3f; accel.z_raw = hil_state.zacc / 9.81f * 1e3f; accel.x = hil_state.xacc; accel.y = hil_state.yacc; accel.z = hil_state.zacc; accel.temperature = 25.0f; accel.timestamp = hrt_absolute_time(); if (pub_hil_accel < 0) { pub_hil_accel = orb_advertise(ORB_ID(sensor_accel), &accel); } else { orb_publish(ORB_ID(sensor_accel), pub_hil_accel, &accel); } /* fill in HIL battery status */ hil_battery_status.timestamp = hrt_absolute_time(); hil_battery_status.voltage_v = 11.1f; hil_battery_status.current_a = 10.0f; /* lazily publish the battery voltage */ if (pub_hil_battery > 0) { orb_publish(ORB_ID(battery_status), pub_hil_battery, &hil_battery_status); } else { pub_hil_battery = orb_advertise(ORB_ID(battery_status), &hil_battery_status); } } if (msg->msgid == MAVLINK_MSG_ID_MANUAL_CONTROL) { mavlink_manual_control_t man; mavlink_msg_manual_control_decode(msg, &man); struct rc_channels_s rc_hil; memset(&rc_hil, 0, sizeof(rc_hil)); static orb_advert_t rc_pub = 0; rc_hil.timestamp = hrt_absolute_time(); rc_hil.chan_count = 4; rc_hil.chan[0].scaled = man.x / 1000.0f; rc_hil.chan[1].scaled = man.y / 1000.0f; rc_hil.chan[2].scaled = man.r / 1000.0f; rc_hil.chan[3].scaled = man.z / 1000.0f; struct manual_control_setpoint_s mc; static orb_advert_t mc_pub = 0; int manual_sub = orb_subscribe(ORB_ID(manual_control_setpoint)); /* get a copy first, to prevent altering values that are not sent by the mavlink command */ orb_copy(ORB_ID(manual_control_setpoint), manual_sub, &mc); mc.timestamp = rc_hil.timestamp; mc.roll = man.x / 1000.0f; mc.pitch = man.y / 1000.0f; mc.yaw = man.r / 1000.0f; mc.throttle = man.z / 1000.0f; /* fake RC channels with manual control input from simulator */ if (rc_pub == 0) { rc_pub = orb_advertise(ORB_ID(rc_channels), &rc_hil); } else { orb_publish(ORB_ID(rc_channels), rc_pub, &rc_hil); } if (mc_pub == 0) { mc_pub = orb_advertise(ORB_ID(manual_control_setpoint), &mc); } else { orb_publish(ORB_ID(manual_control_setpoint), mc_pub, &mc); } } } }
bool MavESP8266Component::handleMessage(MavESP8266Bridge* sender, mavlink_message_t* message) { // // TODO: These response messages need to be queued up and sent as part of the main loop and not all // at once from here. // //----------------------------------------------- //-- MAVLINK_MSG_ID_PARAM_SET if(message->msgid == MAVLINK_MSG_ID_PARAM_SET) { mavlink_param_set_t param; mavlink_msg_param_set_decode(message, ¶m); DEBUG_LOG("MAVLINK_MSG_ID_PARAM_SET: %u %s\n", param.target_component, param.param_id); if(param.target_component == MAV_COMP_ID_UDP_BRIDGE) { _handleParamSet(sender, ¶m); return true; } //----------------------------------------------- //-- MAVLINK_MSG_ID_COMMAND_LONG } else if(message->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(message, &cmd); if(cmd.target_component == MAV_COMP_ID_ALL || cmd.target_component == MAV_COMP_ID_UDP_BRIDGE) { _handleCmdLong(sender, &cmd, cmd.target_component); //-- If it was directed to us, eat it and loop if(cmd.target_component == MAV_COMP_ID_UDP_BRIDGE) { return true; } } //----------------------------------------------- //-- MAVLINK_MSG_ID_PARAM_REQUEST_LIST } else if(message->msgid == MAVLINK_MSG_ID_PARAM_REQUEST_LIST) { mavlink_param_request_list_t param; mavlink_msg_param_request_list_decode(message, ¶m); DEBUG_LOG("MAVLINK_MSG_ID_PARAM_REQUEST_LIST: %u\n", param.target_component); if(param.target_component == MAV_COMP_ID_ALL || param.target_component == MAV_COMP_ID_UDP_BRIDGE) { _handleParamRequestList(sender); } //----------------------------------------------- //-- MAVLINK_MSG_ID_PARAM_REQUEST_READ } else if(message->msgid == MAVLINK_MSG_ID_PARAM_REQUEST_READ) { mavlink_param_request_read_t param; mavlink_msg_param_request_read_decode(message, ¶m); //-- This component or all components? if(param.target_component == MAV_COMP_ID_ALL || param.target_component == MAV_COMP_ID_UDP_BRIDGE) { //-- If asking for hash, respond and pass through if(strncmp(param.param_id, kHASH_PARAM, MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN) == 0) { _sendParameter(sender, kHASH_PARAM, getWorld()->getParameters()->paramHashCheck(), 0xFFFF); } else { _handleParamRequestRead(sender, ¶m); //-- If this was addressed to me only eat message if(param.target_component == MAV_COMP_ID_UDP_BRIDGE) { //-- Eat message (don't send it to FC) return true; } } } } //-- Couldn't handle the message, pass on return false; }
static void handle_message(mavlink_message_t *msg) { if (msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) || (cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { //check for MAVLINK terminate command"mavlink offb rcv" if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && ((int)cmd_mavlink.param1) == 3) { /* This is the link shutdown command, terminate mavlink*/ printf("[mavlink] Terminating .. \n"); fflush(stdout); usleep(50000); /* terminate other threads and this thread*/ thread_should_exit = true; } else { /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = cmd_mavlink.param1; vcmd.param2 = cmd_mavlink.param2; vcmd.param3 = cmd_mavlink.param3; vcmd.param4 = cmd_mavlink.param4; vcmd.param5 = cmd_mavlink.param5; vcmd.param6 = cmd_mavlink.param6; vcmd.param7 = cmd_mavlink.param7; vcmd.command = cmd_mavlink.command; vcmd.target_system = cmd_mavlink.target_system; vcmd.target_component = cmd_mavlink.target_component; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = cmd_mavlink.confirmation; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } /* publish */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } } // if (msg->msgid == MAVLINK_MSG_ID_OPTICAL_FLOW) { // mavlink_optical_flow_t flow; // mavlink_msg_optical_flow_decode(msg, &flow); // // struct optical_flow_s f; // // f.timestamp = hrt_absolute_time(); // f.flow_raw_x = flow.flow_x; // f.flow_raw_y = flow.flow_y; // f.flow_comp_x_m = flow.flow_comp_m_x; // f.flow_comp_y_m = flow.flow_comp_m_y; // f.ground_distance_m = flow.ground_distance; // f.quality = flow.quality; // f.sensor_id = flow.sensor_id; // // /* check if topic is advertised */ // if (flow_pub <= 0) { // flow_pub = orb_advertise(ORB_ID(optical_flow), &f); // } else { // /* publish */ // orb_publish(ORB_ID(optical_flow), flow_pub, &f); // } // // } // // if (msg->msgid == MAVLINK_MSG_ID_SET_MODE) { // /* Set mode on request */ // mavlink_set_mode_t new_mode; // mavlink_msg_set_mode_decode(msg, &new_mode); // // /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ // vcmd.param1 = new_mode.base_mode; // vcmd.param2 = new_mode.custom_mode; // vcmd.param3 = 0; // vcmd.param4 = 0; // vcmd.param5 = 0; // vcmd.param6 = 0; // vcmd.param7 = 0; // vcmd.command = MAV_CMD_DO_SET_MODE; // vcmd.target_system = new_mode.target_system; // vcmd.target_component = MAV_COMP_ID_ALL; // vcmd.source_system = msg->sysid; // vcmd.source_component = msg->compid; // vcmd.confirmation = 1; // // /* check if topic is advertised */ // if (cmd_pub <= 0) { // cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); // } else { // /* create command */ // orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); // } // } // // /* Handle Vicon position estimates */ // if (msg->msgid == MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE) { // mavlink_vicon_position_estimate_t pos; // mavlink_msg_vicon_position_estimate_decode(msg, &pos); // // vicon_position.x = pos.x; // vicon_position.y = pos.y; // vicon_position.z = pos.z; // // if (vicon_position_pub <= 0) { // vicon_position_pub = orb_advertise(ORB_ID(vehicle_vicon_position), &vicon_position); // } else { // orb_publish(ORB_ID(vehicle_vicon_position), vicon_position_pub, &vicon_position); // } // } // // /* Handle quadrotor motor setpoints */ // // if (msg->msgid == MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST) { // mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t quad_motors_setpoint; // mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(msg, &quad_motors_setpoint); // // if (mavlink_system.sysid < 4) { // // /* switch to a receiving link mode */ // gcs_link = false; // // /* // * rate control mode - defined by MAVLink // */ // // uint8_t ml_mode = 0; // bool ml_armed = false; // // switch (quad_motors_setpoint.mode) { // case 0: // ml_armed = false; // break; // case 1: // ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_RATES; // ml_armed = true; // // break; // case 2: // ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_ATTITUDE; // ml_armed = true; // // break; // case 3: // ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_VELOCITY; // break; // case 4: // ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_POSITION; // break; // } // // offboard_control_sp.p1 = (float)quad_motors_setpoint.roll[mavlink_system.sysid-1] / (float)INT16_MAX; // offboard_control_sp.p2 = (float)quad_motors_setpoint.pitch[mavlink_system.sysid-1] / (float)INT16_MAX; // offboard_control_sp.p3= (float)quad_motors_setpoint.yaw[mavlink_system.sysid-1] / (float)INT16_MAX; // offboard_control_sp.p4 = (float)quad_motors_setpoint.thrust[mavlink_system.sysid-1]/(float)UINT16_MAX; // // if (quad_motors_setpoint.thrust[mavlink_system.sysid-1] == 0) { // ml_armed = false; // } // // offboard_control_sp.armed = ml_armed; // offboard_control_sp.mode = ml_mode; // // offboard_control_sp.timestamp = hrt_absolute_time(); // // /* check if topic has to be advertised */ // if (offboard_control_sp_pub <= 0) { // offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); // } else { // /* Publish */ // orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); // } // } // } // Attitude MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT // TODO update mavlink message to attitude yaw_rate if (msg->msgid == MAVLINK_MSG_ID_ROLL_PITCH_YAW_THRUST_SETPOINT) { mavlink_roll_pitch_yaw_thrust_setpoint_t attitude_setpoint_mavlink_msg; mavlink_msg_roll_pitch_yaw_thrust_setpoint_decode(msg, &attitude_setpoint_mavlink_msg); offboard_control_sp.mode = OFFBOARD_CONTROL_MODE_ATT_YAW_RATE; offboard_control_sp.p1 = attitude_setpoint_mavlink_msg.roll; offboard_control_sp.p2 = attitude_setpoint_mavlink_msg.pitch; offboard_control_sp.p3 = attitude_setpoint_mavlink_msg.yaw; offboard_control_sp.p4 = attitude_setpoint_mavlink_msg.thrust; offboard_control_sp.timestamp = hrt_absolute_time(); if (attitude_setpoint_mavlink_msg.thrust > 0) { offboard_control_sp.armed = true; } else { offboard_control_sp.armed = false; } /* check if topic has to be advertised */ // TODO for RC channel use the manual_control_setpoint instead of offboard_control_setpoint if (offboard_control_sp_pub <= 0) { offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); } else { /* Publish */ orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); } } // end attitude // Rate if (msg->msgid == MAVLINK_MSG_ID_ROLL_PITCH_YAW_SPEED_THRUST_SETPOINT) { mavlink_roll_pitch_yaw_speed_thrust_setpoint_t rate_setpoint_mavlink_msg; mavlink_msg_roll_pitch_yaw_speed_thrust_setpoint_decode(msg, &rate_setpoint_mavlink_msg); offboard_control_sp.mode = OFFBOARD_CONTROL_MODE_DIRECT_RATES; offboard_control_sp.p1 = rate_setpoint_mavlink_msg.roll_speed; offboard_control_sp.p2 = rate_setpoint_mavlink_msg.pitch_speed; offboard_control_sp.p3 = rate_setpoint_mavlink_msg.yaw_speed; offboard_control_sp.p4 = rate_setpoint_mavlink_msg.thrust; offboard_control_sp.timestamp = hrt_absolute_time(); if (rate_setpoint_mavlink_msg.thrust > 0) { offboard_control_sp.armed = true; } else { offboard_control_sp.armed = false; } /* check if topic has to be advertised */ if (offboard_control_sp_pub <= 0) { offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); } else { /* Publish */ orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); } } // end rate /* // parameter if (msg->msgid == MAVLINK_MSG_ID_PARAM_SET) { mavlink_param_set_t param_mavlink_msg; mavlink_msg_param_set_decode(msg, ¶m_mavlink_msg); printf("%s %3.5f \n",param_mavlink_msg.param_id, param_mavlink_msg.param_value); param_t param_ptr = param_find(param_mavlink_msg.param_id); param_set(param_ptr, ¶m_mavlink_msg.param_value); } if (msg->msgid == MAVLINK_MSG_ID_PARAM_REQUEST_READ) { mavlink_param_request_read_t read_param_mavlink_msg; mavlink_msg_param_request_read_decode(msg, &read_param_mavlink_msg); printf("%s \n",read_param_mavlink_msg.param_id); param_t param_ptr = param_find(read_param_mavlink_msg.param_id); float value; param_get(param_ptr, &value); int type= param_type(param_ptr); int count= param_count(); int index= param_get_index(param_ptr); mavlink_msg_param_value_send(chan, read_param_mavlink_msg.param_id, value, type, count, index); } if (msg->msgid == MAVLINK_MSG_ID_PARAM_REQUEST_LIST) { int count= param_count(); int type; float value; char* param_id; param_t param_ptr; for(int index=0; index<count; index++) { param_ptr=param_for_index(index); param_id=param_name(param_ptr); param_get(param_ptr, &value); type=type= param_type(param_ptr); mavlink_msg_param_value_send(chan, param_id, value, type, count, index); sleep(1); } }*/ }
void CcUnpackCycle(SerialDriver *sdp){ mavlink_message_t msg; mavlink_status_t status; msg_t c = 0; msg_t prev_c = 0; while (!chThdShouldTerminate()) { if (!cc_port_ready()){ chThdSleepMilliseconds(50); continue; } else{ /* Try to get an escaped with DLE symbols message */ c = sdGetTimeout((SerialDriver *)sdp, MS2ST(50)); if (c == Q_TIMEOUT) continue; prev_c = c; if (prev_c == DLE){ prev_c = 0; /* set it to any just not DLE nor ETX */ c = sdGetTimeout((SerialDriver *)sdp, MS2ST(50)); if (c == Q_TIMEOUT) continue; } } if (mavlink_parse_char(MAVLINK_COMM_0, (uint8_t)c, &msg, &status)) { switch(msg.msgid){ case MAVLINK_MSG_ID_COMMAND_LONG: mavlink_msg_command_long_decode(&msg, &mavlink_command_long_struct); if (mavlink_command_long_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_command_long, EVMSK_MAVLINK_COMMAND_LONG); break; case MAVLINK_MSG_ID_PARAM_REQUEST_READ: mavlink_msg_param_request_read_decode(&msg, &mavlink_param_request_read_struct); if (mavlink_param_request_read_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_param_request_read, EVMSK_MAVLINK_PARAM_REQUEST_READ); break; case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: mavlink_msg_param_request_list_decode(&msg, &mavlink_param_request_list_struct); if (mavlink_param_request_list_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_param_request_list, EVMSK_MAVLINK_PARAM_REQUEST_LIST); break; case MAVLINK_MSG_ID_PARAM_SET: mavlink_msg_param_set_decode(&msg, &mavlink_param_set_struct); if (mavlink_param_set_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_param_set, EVMSK_MAVLINK_PARAM_SET); break; case MAVLINK_MSG_ID_OBLIQUE_STORAGE_REQUEST_CC: mavlink_msg_oblique_storage_request_cc_decode(&msg, &mavlink_oblique_storage_request_cc_struct); if (mavlink_oblique_storage_request_cc_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_oblique_storage_request_cc, EVMSK_MAVLINK_OBLIQUE_STORAGE_REQUEST_CC); break; case MAVLINK_MSG_ID_OBLIQUE_STORAGE_REQUEST_COUNT_CC: mavlink_msg_oblique_storage_request_count_cc_decode(&msg, &mavlink_oblique_storage_request_count_cc_struct); if (mavlink_oblique_storage_request_count_cc_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_oblique_storage_request_count_cc, EVMSK_MAVLINK_OBLIQUE_STORAGE_REQUEST_COUNT_CC); break; case MAVLINK_MSG_ID_HEARTBEAT_CC: mavlink_msg_heartbeat_cc_decode(&msg, &mavlink_heartbeat_cc_struct); // if (mavlink_heartbeat_cc_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_heartbeat_cc, EVMSK_MAVLINK_HEARTBEAT_CC); break; case MAVLINK_MSG_ID_STATUSTEXT: mavlink_msg_statustext_decode(&msg, &mavlink_statustext_struct); // if (mavlink_statustext_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_statustext, EVMSK_MAVLINK_STATUSTEXT); break; case MAVLINK_MSG_ID_OBLIQUE_AGPS: mavlink_msg_oblique_agps_decode(&msg, &mavlink_oblique_agps_struct); if (mavlink_oblique_agps_struct.target_system == mavlink_system_struct.sysid) chEvtBroadcastFlags(&event_mavlink_oblique_agps, EVMSK_MAVLINK_OBLIQUE_AGPS); break; default: break; } } } }
void mavlink_pm_message_handler(const mavlink_channel_t chan, const mavlink_message_t *msg) { switch (msg->msgid) { case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { /* Start sending parameters */ mavlink_pm_start_queued_send(); mavlink_missionlib_send_gcs_string("[mavlink pm] sending list"); } break; case MAVLINK_MSG_ID_PARAM_SET: { /* Handle parameter setting */ if (msg->msgid == MAVLINK_MSG_ID_PARAM_SET) { mavlink_param_set_t mavlink_param_set; mavlink_msg_param_set_decode(msg, &mavlink_param_set); if (mavlink_param_set.target_system == mavlink_system.sysid && ((mavlink_param_set.target_component == mavlink_system.compid) || (mavlink_param_set.target_component == MAV_COMP_ID_ALL))) { /* local name buffer to enforce null-terminated string */ char name[MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN+1]; strncpy(name, mavlink_param_set.param_id, MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN); /* enforce null termination */ name[MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN] = '\0'; /* attempt to find parameter, set and send it */ param_t param = param_find(name); if (param == PARAM_INVALID) { char buf[MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN]; sprintf(buf, "[mavlink pm] unknown: %s", name); mavlink_missionlib_send_gcs_string(buf); } else { /* set and send parameter */ param_set(param, &(mavlink_param_set.param_value)); mavlink_pm_send_param(param); } } } } break; case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { mavlink_param_request_read_t mavlink_param_request_read; mavlink_msg_param_request_read_decode(msg, &mavlink_param_request_read); if (mavlink_param_request_read.target_system == mavlink_system.sysid && ((mavlink_param_request_read.target_component == mavlink_system.compid) || (mavlink_param_request_read.target_component == MAV_COMP_ID_ALL))) { /* when no index is given, loop through string ids and compare them */ if (mavlink_param_request_read.param_index == -1) { /* local name buffer to enforce null-terminated string */ char name[MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN+1]; strncpy(name, mavlink_param_request_read.param_id, MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN); /* enforce null termination */ name[MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN] = '\0'; /* attempt to find parameter and send it */ mavlink_pm_send_param_for_name(name); } else { /* when index is >= 0, send this parameter again */ mavlink_pm_send_param_for_index(mavlink_param_request_read.param_index); } } } break; case MAVLINK_MSG_ID_COMMAND_LONG: { mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); uint8_t result = MAV_RESULT_UNSUPPORTED; if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) ||(cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { /* preflight parameter load / store */ if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_STORAGE) { /* Read all parameters from EEPROM to RAM */ if (((int)(cmd_mavlink.param1)) == 0) { /* read all parameters from EEPROM to RAM */ int read_ret = mavlink_pm_load_eeprom(); if (read_ret == OK) { //printf("[mavlink pm] Loaded EEPROM params in RAM\n"); mavlink_missionlib_send_gcs_string("[mavlink pm] OK loaded EEPROM params"); result = MAV_RESULT_ACCEPTED; } else if (read_ret == 1) { mavlink_missionlib_send_gcs_string("[mavlink pm] No stored parameters to load"); result = MAV_RESULT_ACCEPTED; } else { if (read_ret < -1) { mavlink_missionlib_send_gcs_string("[mavlink pm] ERR loading params from EEPROM"); } else { mavlink_missionlib_send_gcs_string("[mavlink pm] ERR loading params, no EEPROM found"); } result = MAV_RESULT_FAILED; } } else if (((int)(cmd_mavlink.param1)) == 1) { /* write all parameters from RAM to EEPROM */ int write_ret = mavlink_pm_save_eeprom(); if (write_ret == OK) { mavlink_missionlib_send_gcs_string("[mavlink pm] OK params written to EEPROM"); result = MAV_RESULT_ACCEPTED; } else { if (write_ret < -1) { mavlink_missionlib_send_gcs_string("[mavlink pm] ERR writing params to EEPROM"); } else { mavlink_missionlib_send_gcs_string("[mavlink pm] ERR writing params, no EEPROM found"); } result = MAV_RESULT_FAILED; } } else { //fprintf(stderr, "[mavlink pm] refusing unsupported storage request\n"); mavlink_missionlib_send_gcs_string("[mavlink pm] refusing unsupported STOR request"); result = MAV_RESULT_UNSUPPORTED; } } } /* send back command result */ //mavlink_msg_command_ack_send(chan, cmd.command, result); } break; } }
void cDataLink::handleMessage(mavlink_message_t* msg) { uint16_t len; int bytes_sent; mavlink_param_set_t set; mavlink_msg_param_set_decode(msg, &set); //uint8_t result = MAV_RESULT_UNSUPPORTED; switch (msg->msgid) { case MAVLINK_MSG_ID_COMMAND_LONG: { // decode mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); switch(packet.command) { case MAV_CMD_PREFLIGHT_CALIBRATION: // 1: Gyro calibration if (packet.param2 == 1) { printf("Magnetometer calibration!\n"); signal_mag_calibration(); } // 3: Ground pressure // 4: Radio calibration // 5: Accelerometer calibration // Parameter 6 & 7 not pre-defined // result = MAV_RESULT_ACCEPTED; break; default: // result = MAV_RESULT_UNSUPPORTED; break; } // switch packet.command // mavlink_msg_command_ack_send(chan, // packet.command, // result); break; } // case MAVLINK_MSG_ID_COMMAND_LONG case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { mavlink_param_request_read_t packet; mavlink_msg_param_request_read_decode(msg, &packet); mavlink_msg_param_value_pack( packet.target_system, packet.target_component, msg, cParameter::get_instances()->at(packet.param_index)->get_name().c_str(), *(cParameter::get_instances()->at(packet.param_index)->get_value()), MAV_PARAM_TYPE_REAL32, cParameter::get_instances()->size(), // param_count = Anzahl der Parameter packet.param_index); // param_index = Nummer f. aktellen Parameter len = mavlink_msg_to_send_buffer(m_buf, msg); bytes_sent = sendto(sock, m_buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in)); (void)bytes_sent; //avoid compiler warning break; } case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { // Start sending parameters for(std::vector<cParameter*>::iterator it=cParameter::get_instances()->begin(); it!=cParameter::get_instances()->end(); ++it) { mavlink_msg_param_value_pack( 1, MAV_COMP_ID_SYSTEM_CONTROL, msg, (*it)->get_name().c_str(), *((*it)->get_value()), //Iterator goes to vector list with cParameter pointers. Get value returns a pointer to the component value -> again dereference MAV_PARAM_TYPE_REAL32, cParameter::get_instances()->size(), // param_count = Anzahl der Parameter std::distance(cParameter::get_instances()->begin(),it)); // param_index = Nummer f. aktellen Parameter len = mavlink_msg_to_send_buffer(m_buf, msg); bytes_sent = sendto(sock, m_buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in)); (void)bytes_sent; //avoid compiler warning boost::this_thread::sleep(boost::posix_time::milliseconds(10)); } break; } case MAVLINK_MSG_ID_PARAM_SET: { mavlink_param_set_t packet; mavlink_msg_param_set_decode(msg, &packet); std::vector<cParameter*>::iterator it = cParameter::exist(packet.param_id); if( cParameter::get_instances()->end() != it ) { (*it)->set_value(packet.param_value); mavlink_msg_param_value_pack( packet.target_system, packet.target_component, msg, (*it)->get_name().c_str(), *((*it)->get_value()), MAV_PARAM_TYPE_REAL32, cParameter::get_instances()->size(), // param_count = Anzahl der Parameter std::distance(cParameter::get_instances()->begin(),it)); // param_index = Nummer f. aktellen Parameter len = mavlink_msg_to_send_buffer(m_buf, msg); bytes_sent = sendto(sock, m_buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in)); (void)bytes_sent; //avoid compiler warning } break; } default: { printf("msg->msgid not known: %d\n", msg->msgid); } break; }// switch msgid }
void GCS_MAVLINK::handleMessage(mavlink_message_t* msg) { switch (msg->msgid) { // If we are currently operating as a proxy for a remote, // alas we have to look inside each packet to see if its for us or for the remote case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: { handle_request_data_stream(msg, true); break; } case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { handle_param_request_list(msg); break; } case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { handle_param_request_read(msg); break; } case MAVLINK_MSG_ID_PARAM_SET: { handle_param_set(msg, NULL); break; } case MAVLINK_MSG_ID_HEARTBEAT: break; case MAVLINK_MSG_ID_COMMAND_LONG: { // decode mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); uint8_t result = MAV_RESULT_UNSUPPORTED; // do command send_text_P(SEVERITY_LOW,PSTR("command received: ")); switch(packet.command) { case MAV_CMD_PREFLIGHT_CALIBRATION: { if (is_equal(packet.param1,1.0f)) { tracker.ins.init_gyro(); if (tracker.ins.gyro_calibrated_ok_all()) { tracker.ahrs.reset_gyro_drift(); result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } if (is_equal(packet.param3,1.0f)) { tracker.init_barometer(); // zero the altitude difference on next baro update tracker.nav_status.need_altitude_calibration = true; } if (is_equal(packet.param4,1.0f)) { // Cant trim radio } else if (is_equal(packet.param5,1.0f)) { float trim_roll, trim_pitch; AP_InertialSensor_UserInteract_MAVLink interact(this); if(tracker.ins.calibrate_accel(&interact, trim_roll, trim_pitch)) { // reset ahrs's trim to suggested values from calibration routine tracker.ahrs.set_trim(Vector3f(trim_roll, trim_pitch, 0)); } } else if (is_equal(packet.param5,2.0f)) { // accel trim float trim_roll, trim_pitch; if(tracker.ins.calibrate_trim(trim_roll, trim_pitch)) { // reset ahrs's trim to suggested values from calibration routine tracker.ahrs.set_trim(Vector3f(trim_roll, trim_pitch, 0)); result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } result = MAV_RESULT_ACCEPTED; break; } case MAV_CMD_COMPONENT_ARM_DISARM: if (packet.target_component == MAV_COMP_ID_SYSTEM_CONTROL) { if (is_equal(packet.param1,1.0f)) { tracker.arm_servos(); result = MAV_RESULT_ACCEPTED; } else if (is_zero(packet.param1)) { tracker.disarm_servos(); result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_UNSUPPORTED; } } else { result = MAV_RESULT_UNSUPPORTED; } break; case MAV_CMD_DO_SET_MODE: switch ((uint16_t)packet.param1) { case MAV_MODE_MANUAL_ARMED: case MAV_MODE_MANUAL_DISARMED: tracker.set_mode(MANUAL); result = MAV_RESULT_ACCEPTED; break; case MAV_MODE_AUTO_ARMED: case MAV_MODE_AUTO_DISARMED: tracker.set_mode(AUTO); result = MAV_RESULT_ACCEPTED; break; default: result = MAV_RESULT_UNSUPPORTED; } break; case MAV_CMD_DO_SET_SERVO: if (tracker.servo_test_set_servo(packet.param1, packet.param2)) { result = MAV_RESULT_ACCEPTED; } break; // mavproxy/mavutil sends this when auto command is entered case MAV_CMD_MISSION_START: tracker.set_mode(AUTO); result = MAV_RESULT_ACCEPTED; break; case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN: { if (is_equal(packet.param1,1.0f) || is_equal(packet.param1,3.0f)) { // when packet.param1 == 3 we reboot to hold in bootloader hal.scheduler->reboot(is_equal(packet.param1,3.0f)); result = MAV_RESULT_ACCEPTED; } break; } case MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES: { if (is_equal(packet.param1,1.0f)) { tracker.gcs[chan-MAVLINK_COMM_0].send_autopilot_version(); result = MAV_RESULT_ACCEPTED; } break; } default: break; } mavlink_msg_command_ack_send( chan, packet.command, result); break; } // When mavproxy 'wp sethome' case MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST: { // decode mavlink_mission_write_partial_list_t packet; mavlink_msg_mission_write_partial_list_decode(msg, &packet); if (packet.start_index == 0) { // New home at wp index 0. Ask for it waypoint_receiving = true; waypoint_request_i = 0; waypoint_request_last = 0; send_message(MSG_NEXT_WAYPOINT); waypoint_receiving = true; } break; } // XXX receive a WP from GCS and store in EEPROM if it is HOME case MAVLINK_MSG_ID_MISSION_ITEM: { // decode mavlink_mission_item_t packet; uint8_t result = MAV_MISSION_ACCEPTED; mavlink_msg_mission_item_decode(msg, &packet); struct Location tell_command = {}; switch (packet.frame) { case MAV_FRAME_MISSION: case MAV_FRAME_GLOBAL: { tell_command.lat = 1.0e7f*packet.x; // in as DD converted to * t7 tell_command.lng = 1.0e7f*packet.y; // in as DD converted to * t7 tell_command.alt = packet.z*1.0e2f; // in as m converted to cm tell_command.options = 0; // absolute altitude break; } #ifdef MAV_FRAME_LOCAL_NED case MAV_FRAME_LOCAL_NED: // local (relative to home position) { tell_command.lat = 1.0e7f*ToDeg(packet.x/ (RADIUS_OF_EARTH*cosf(ToRad(home.lat/1.0e7f)))) + home.lat; tell_command.lng = 1.0e7f*ToDeg(packet.y/RADIUS_OF_EARTH) + home.lng; tell_command.alt = -packet.z*1.0e2f; tell_command.options = MASK_OPTIONS_RELATIVE_ALT; break; } #endif #ifdef MAV_FRAME_LOCAL case MAV_FRAME_LOCAL: // local (relative to home position) { tell_command.lat = 1.0e7f*ToDeg(packet.x/ (RADIUS_OF_EARTH*cosf(ToRad(home.lat/1.0e7f)))) + home.lat; tell_command.lng = 1.0e7f*ToDeg(packet.y/RADIUS_OF_EARTH) + home.lng; tell_command.alt = packet.z*1.0e2f; tell_command.options = MASK_OPTIONS_RELATIVE_ALT; break; } #endif case MAV_FRAME_GLOBAL_RELATIVE_ALT: // absolute lat/lng, relative altitude { tell_command.lat = 1.0e7f * packet.x; // in as DD converted to * t7 tell_command.lng = 1.0e7f * packet.y; // in as DD converted to * t7 tell_command.alt = packet.z * 1.0e2f; tell_command.options = MASK_OPTIONS_RELATIVE_ALT; // store altitude relative!! Always!! break; } default: result = MAV_MISSION_UNSUPPORTED_FRAME; break; } if (result != MAV_MISSION_ACCEPTED) goto mission_failed; // Check if receiving waypoints (mission upload expected) if (!waypoint_receiving) { result = MAV_MISSION_ERROR; goto mission_failed; } // check if this is the HOME wp if (packet.seq == 0) { tracker.set_home(tell_command); // New home in EEPROM send_text_P(SEVERITY_LOW,PSTR("new HOME received")); waypoint_receiving = false; } mission_failed: // we are rejecting the mission/waypoint mavlink_msg_mission_ack_send( chan, msg->sysid, msg->compid, result); break; } case MAVLINK_MSG_ID_MANUAL_CONTROL: { mavlink_manual_control_t packet; mavlink_msg_manual_control_decode(msg, &packet); tracker.tracking_manual_control(packet); break; } case MAVLINK_MSG_ID_GLOBAL_POSITION_INT: { // decode mavlink_global_position_int_t packet; mavlink_msg_global_position_int_decode(msg, &packet); tracker.tracking_update_position(packet); break; } case MAVLINK_MSG_ID_SCALED_PRESSURE: { // decode mavlink_scaled_pressure_t packet; mavlink_msg_scaled_pressure_decode(msg, &packet); tracker.tracking_update_pressure(packet); break; } case MAVLINK_MSG_ID_SET_MODE: { handle_set_mode(msg, FUNCTOR_BIND(&tracker, &Tracker::mavlink_set_mode, bool, uint8_t)); break; } #if HAL_CPU_CLASS > HAL_CPU_CLASS_16 case MAVLINK_MSG_ID_SERIAL_CONTROL: handle_serial_control(msg, tracker.gps); break; case MAVLINK_MSG_ID_GPS_INJECT_DATA: handle_gps_inject(msg, tracker.gps); break; #endif case MAVLINK_MSG_ID_AUTOPILOT_VERSION_REQUEST: tracker.gcs[chan-MAVLINK_COMM_0].send_autopilot_version(); break; } // end switch } // end handle mavlink
static void handle_message(mavlink_message_t *msg) { if (msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) || (cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { //check for MAVLINK terminate command if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && ((int)cmd_mavlink.param1) == 3) { /* This is the link shutdown command, terminate mavlink */ warnx("terminating..."); fflush(stdout); usleep(50000); /* terminate other threads and this thread */ thread_should_exit = true; } else { /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = cmd_mavlink.param1; vcmd.param2 = cmd_mavlink.param2; vcmd.param3 = cmd_mavlink.param3; vcmd.param4 = cmd_mavlink.param4; vcmd.param5 = cmd_mavlink.param5; vcmd.param6 = cmd_mavlink.param6; vcmd.param7 = cmd_mavlink.param7; vcmd.command = cmd_mavlink.command; vcmd.target_system = cmd_mavlink.target_system; vcmd.target_component = cmd_mavlink.target_component; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = cmd_mavlink.confirmation; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } /* publish */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } } if (msg->msgid == MAVLINK_MSG_ID_OPTICAL_FLOW) { mavlink_optical_flow_t flow; mavlink_msg_optical_flow_decode(msg, &flow); struct optical_flow_s f; f.timestamp = hrt_absolute_time(); f.flow_raw_x = flow.flow_x; f.flow_raw_y = flow.flow_y; f.flow_comp_x_m = flow.flow_comp_m_x; f.flow_comp_y_m = flow.flow_comp_m_y; f.ground_distance_m = flow.ground_distance; f.quality = flow.quality; f.sensor_id = flow.sensor_id; /* check if topic is advertised */ if (flow_pub <= 0) { flow_pub = orb_advertise(ORB_ID(optical_flow), &f); } else { /* publish */ orb_publish(ORB_ID(optical_flow), flow_pub, &f); } } if (msg->msgid == MAVLINK_MSG_ID_SET_MODE) { /* Set mode on request */ mavlink_set_mode_t new_mode; mavlink_msg_set_mode_decode(msg, &new_mode); /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = new_mode.base_mode; vcmd.param2 = new_mode.custom_mode; vcmd.param3 = 0; vcmd.param4 = 0; vcmd.param5 = 0; vcmd.param6 = 0; vcmd.param7 = 0; vcmd.command = MAV_CMD_DO_SET_MODE; vcmd.target_system = new_mode.target_system; vcmd.target_component = MAV_COMP_ID_ALL; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = 1; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } else { /* create command */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } /* Handle Vicon position estimates */ if (msg->msgid == MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE) { mavlink_vicon_position_estimate_t pos; mavlink_msg_vicon_position_estimate_decode(msg, &pos); vicon_position.x = pos.x; vicon_position.y = pos.y; vicon_position.z = pos.z; if (vicon_position_pub <= 0) { vicon_position_pub = orb_advertise(ORB_ID(vehicle_vicon_position), &vicon_position); } else { orb_publish(ORB_ID(vehicle_vicon_position), vicon_position_pub, &vicon_position); } } //Mavlink Message from the onboard computer / laserscanner: if (msg->msgid == MAVLINK_MSG_ID_DANGER) { mavlink_danger_t dang; mavlink_msg_danger_decode(msg, &dang); struct danger_s d; d.time_usec = hrt_absolute_time(); d.sensor_id = dang.sensor_id; d.danger_level = dang.danger_level; d.danger_dist = dang.danger_dist; d.danger_dir = dang.danger_dir; d.avoid_level = dang.avoid_level; d.avoid_dir = dang.avoid_dir; //check if topic is advertised if (danger_pub <= 0) { danger_pub = orb_advertise(ORB_ID(danger), &d); } else { // publish orb_publish(ORB_ID(danger), danger_pub, &d); } } /* Handle quadrotor motor setpoints */ if (msg->msgid == MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST) { mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t quad_motors_setpoint; mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(msg, &quad_motors_setpoint); if (mavlink_system.sysid < 4) { /* switch to a receiving link mode */ gcs_link = false; /* * rate control mode - defined by MAVLink */ uint8_t ml_mode = 0; bool ml_armed = false; switch (quad_motors_setpoint.mode) { case 0: ml_armed = false; break; case 1: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_RATES; ml_armed = true; break; case 2: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_ATTITUDE; ml_armed = true; break; case 3: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_VELOCITY; break; case 4: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_POSITION; break; } offboard_control_sp.p1 = (float)quad_motors_setpoint.roll[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p2 = (float)quad_motors_setpoint.pitch[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p3 = (float)quad_motors_setpoint.yaw[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p4 = (float)quad_motors_setpoint.thrust[mavlink_system.sysid - 1] / (float)UINT16_MAX; if (quad_motors_setpoint.thrust[mavlink_system.sysid - 1] == 0) { ml_armed = false; } offboard_control_sp.armed = ml_armed; offboard_control_sp.mode = ml_mode; offboard_control_sp.timestamp = hrt_absolute_time(); /* check if topic has to be advertised */ if (offboard_control_sp_pub <= 0) { offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); } else { /* Publish */ orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); } } } }
static void handle_message(mavlink_message_t *msg) { if (msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd_mavlink; mavlink_msg_command_long_decode(msg, &cmd_mavlink); if (cmd_mavlink.target_system == mavlink_system.sysid && ((cmd_mavlink.target_component == mavlink_system.compid) || (cmd_mavlink.target_component == MAV_COMP_ID_ALL))) { //check for MAVLINK terminate command if (cmd_mavlink.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && ((int)cmd_mavlink.param1) == 3) { /* This is the link shutdown command, terminate mavlink */ printf("[mavlink] Terminating .. \n"); fflush(stdout); usleep(50000); /* terminate other threads and this thread */ thread_should_exit = true; } else { /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = cmd_mavlink.param1; vcmd.param2 = cmd_mavlink.param2; vcmd.param3 = cmd_mavlink.param3; vcmd.param4 = cmd_mavlink.param4; vcmd.param5 = cmd_mavlink.param5; vcmd.param6 = cmd_mavlink.param6; vcmd.param7 = cmd_mavlink.param7; vcmd.command = cmd_mavlink.command; vcmd.target_system = cmd_mavlink.target_system; vcmd.target_component = cmd_mavlink.target_component; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = cmd_mavlink.confirmation; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } /* publish */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } } if (msg->msgid == MAVLINK_MSG_ID_OPTICAL_FLOW) { mavlink_optical_flow_t flow; mavlink_msg_optical_flow_decode(msg, &flow); struct optical_flow_s f; f.timestamp = flow.time_usec; f.flow_raw_x = flow.flow_x; f.flow_raw_y = flow.flow_y; f.flow_comp_x_m = flow.flow_comp_m_x; f.flow_comp_y_m = flow.flow_comp_m_y; f.ground_distance_m = flow.ground_distance; f.quality = flow.quality; f.sensor_id = flow.sensor_id; /* check if topic is advertised */ if (flow_pub <= 0) { flow_pub = orb_advertise(ORB_ID(optical_flow), &f); } else { /* publish */ orb_publish(ORB_ID(optical_flow), flow_pub, &f); } } if (msg->msgid == MAVLINK_MSG_ID_SET_MODE) { /* Set mode on request */ mavlink_set_mode_t new_mode; mavlink_msg_set_mode_decode(msg, &new_mode); /* Copy the content of mavlink_command_long_t cmd_mavlink into command_t cmd */ vcmd.param1 = new_mode.base_mode; vcmd.param2 = new_mode.custom_mode; vcmd.param3 = 0; vcmd.param4 = 0; vcmd.param5 = 0; vcmd.param6 = 0; vcmd.param7 = 0; vcmd.command = MAV_CMD_DO_SET_MODE; vcmd.target_system = new_mode.target_system; vcmd.target_component = MAV_COMP_ID_ALL; vcmd.source_system = msg->sysid; vcmd.source_component = msg->compid; vcmd.confirmation = 1; /* check if topic is advertised */ if (cmd_pub <= 0) { cmd_pub = orb_advertise(ORB_ID(vehicle_command), &vcmd); } else { /* create command */ orb_publish(ORB_ID(vehicle_command), cmd_pub, &vcmd); } } /* Handle Vicon position estimates */ if (msg->msgid == MAVLINK_MSG_ID_VICON_POSITION_ESTIMATE) { mavlink_vicon_position_estimate_t pos; mavlink_msg_vicon_position_estimate_decode(msg, &pos); vicon_position.timestamp = hrt_absolute_time(); vicon_position.x = pos.x; vicon_position.y = pos.y; vicon_position.z = pos.z; vicon_position.roll = pos.roll; vicon_position.pitch = pos.pitch; vicon_position.yaw = pos.yaw; if (vicon_position_pub <= 0) { vicon_position_pub = orb_advertise(ORB_ID(vehicle_vicon_position), &vicon_position); } else { orb_publish(ORB_ID(vehicle_vicon_position), vicon_position_pub, &vicon_position); } } /* Handle quadrotor motor setpoints */ if (msg->msgid == MAVLINK_MSG_ID_SET_QUAD_SWARM_ROLL_PITCH_YAW_THRUST) { mavlink_set_quad_swarm_roll_pitch_yaw_thrust_t quad_motors_setpoint; mavlink_msg_set_quad_swarm_roll_pitch_yaw_thrust_decode(msg, &quad_motors_setpoint); if (mavlink_system.sysid < 4) { /* switch to a receiving link mode */ gcs_link = false; /* * rate control mode - defined by MAVLink */ uint8_t ml_mode = 0; bool ml_armed = false; switch (quad_motors_setpoint.mode) { case 0: ml_armed = false; break; case 1: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_RATES; ml_armed = true; break; case 2: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_ATTITUDE; ml_armed = true; break; case 3: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_VELOCITY; break; case 4: ml_mode = OFFBOARD_CONTROL_MODE_DIRECT_POSITION; break; } offboard_control_sp.p1 = (float)quad_motors_setpoint.roll[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p2 = (float)quad_motors_setpoint.pitch[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p3 = (float)quad_motors_setpoint.yaw[mavlink_system.sysid - 1] / (float)INT16_MAX; offboard_control_sp.p4 = (float)quad_motors_setpoint.thrust[mavlink_system.sysid - 1] / (float)UINT16_MAX; if (quad_motors_setpoint.thrust[mavlink_system.sysid - 1] == 0) { ml_armed = false; } offboard_control_sp.armed = ml_armed; offboard_control_sp.mode = ml_mode; offboard_control_sp.timestamp = hrt_absolute_time(); /* check if topic has to be advertised */ if (offboard_control_sp_pub <= 0) { offboard_control_sp_pub = orb_advertise(ORB_ID(offboard_control_setpoint), &offboard_control_sp); } else { /* Publish */ orb_publish(ORB_ID(offboard_control_setpoint), offboard_control_sp_pub, &offboard_control_sp); } } } /* * Only decode hil messages in HIL mode. * * The HIL mode is enabled by the HIL bit flag * in the system mode. Either send a set mode * COMMAND_LONG message or a SET_MODE message */ if (mavlink_hil_enabled) { uint64_t timestamp = hrt_absolute_time(); /* TODO, set ground_press/ temp during calib */ static const float ground_press = 1013.25f; // mbar static const float ground_tempC = 21.0f; static const float ground_alt = 0.0f; static const float T0 = 273.15; static const float R = 287.05f; static const float g = 9.806f; if (msg->msgid == MAVLINK_MSG_ID_RAW_IMU) { mavlink_raw_imu_t imu; mavlink_msg_raw_imu_decode(msg, &imu); /* packet counter */ static uint16_t hil_counter = 0; static uint16_t hil_frames = 0; static uint64_t old_timestamp = 0; /* sensors general */ hil_sensors.timestamp = imu.time_usec; /* hil gyro */ static const float mrad2rad = 1.0e-3f; hil_sensors.gyro_counter = hil_counter; hil_sensors.gyro_raw[0] = imu.xgyro; hil_sensors.gyro_raw[1] = imu.ygyro; hil_sensors.gyro_raw[2] = imu.zgyro; hil_sensors.gyro_rad_s[0] = imu.xgyro * mrad2rad; hil_sensors.gyro_rad_s[1] = imu.ygyro * mrad2rad; hil_sensors.gyro_rad_s[2] = imu.zgyro * mrad2rad; /* accelerometer */ hil_sensors.accelerometer_counter = hil_counter; static const float mg2ms2 = 9.8f / 1000.0f; hil_sensors.accelerometer_raw[0] = imu.xacc; hil_sensors.accelerometer_raw[1] = imu.yacc; hil_sensors.accelerometer_raw[2] = imu.zacc; hil_sensors.accelerometer_m_s2[0] = mg2ms2 * imu.xacc; hil_sensors.accelerometer_m_s2[1] = mg2ms2 * imu.yacc; hil_sensors.accelerometer_m_s2[2] = mg2ms2 * imu.zacc; hil_sensors.accelerometer_mode = 0; // TODO what is this? hil_sensors.accelerometer_range_m_s2 = 32.7f; // int16 /* adc */ hil_sensors.adc_voltage_v[0] = 0; hil_sensors.adc_voltage_v[1] = 0; hil_sensors.adc_voltage_v[2] = 0; /* magnetometer */ float mga2ga = 1.0e-3f; hil_sensors.magnetometer_counter = hil_counter; hil_sensors.magnetometer_raw[0] = imu.xmag; hil_sensors.magnetometer_raw[1] = imu.ymag; hil_sensors.magnetometer_raw[2] = imu.zmag; hil_sensors.magnetometer_ga[0] = imu.xmag * mga2ga; hil_sensors.magnetometer_ga[1] = imu.ymag * mga2ga; hil_sensors.magnetometer_ga[2] = imu.zmag * mga2ga; hil_sensors.magnetometer_range_ga = 32.7f; // int16 hil_sensors.magnetometer_mode = 0; // TODO what is this hil_sensors.magnetometer_cuttoff_freq_hz = 50.0f; /* publish */ orb_publish(ORB_ID(sensor_combined), pub_hil_sensors, &hil_sensors); // increment counters hil_counter += 1 ; hil_frames += 1 ; // output if ((timestamp - old_timestamp) > 10000000) { printf("receiving hil imu at %d hz\n", hil_frames/10); old_timestamp = timestamp; hil_frames = 0; } } if (msg->msgid == MAVLINK_MSG_ID_HIGHRES_IMU) { mavlink_highres_imu_t imu; mavlink_msg_highres_imu_decode(msg, &imu); /* packet counter */ static uint16_t hil_counter = 0; static uint16_t hil_frames = 0; static uint64_t old_timestamp = 0; /* sensors general */ hil_sensors.timestamp = imu.time_usec; /* hil gyro */ static const float mrad2rad = 1.0e-3f; hil_sensors.gyro_counter = hil_counter; hil_sensors.gyro_raw[0] = imu.xgyro / mrad2rad; hil_sensors.gyro_raw[1] = imu.ygyro / mrad2rad; hil_sensors.gyro_raw[2] = imu.zgyro / mrad2rad; hil_sensors.gyro_rad_s[0] = imu.xgyro; hil_sensors.gyro_rad_s[1] = imu.ygyro; hil_sensors.gyro_rad_s[2] = imu.zgyro; /* accelerometer */ hil_sensors.accelerometer_counter = hil_counter; static const float mg2ms2 = 9.8f / 1000.0f; hil_sensors.accelerometer_raw[0] = imu.xacc / mg2ms2; hil_sensors.accelerometer_raw[1] = imu.yacc / mg2ms2; hil_sensors.accelerometer_raw[2] = imu.zacc / mg2ms2; hil_sensors.accelerometer_m_s2[0] = imu.xacc; hil_sensors.accelerometer_m_s2[1] = imu.yacc; hil_sensors.accelerometer_m_s2[2] = imu.zacc; hil_sensors.accelerometer_mode = 0; // TODO what is this? hil_sensors.accelerometer_range_m_s2 = 32.7f; // int16 /* adc */ hil_sensors.adc_voltage_v[0] = 0; hil_sensors.adc_voltage_v[1] = 0; hil_sensors.adc_voltage_v[2] = 0; /* magnetometer */ float mga2ga = 1.0e-3f; hil_sensors.magnetometer_counter = hil_counter; hil_sensors.magnetometer_raw[0] = imu.xmag / mga2ga; hil_sensors.magnetometer_raw[1] = imu.ymag / mga2ga; hil_sensors.magnetometer_raw[2] = imu.zmag / mga2ga; hil_sensors.magnetometer_ga[0] = imu.xmag; hil_sensors.magnetometer_ga[1] = imu.ymag; hil_sensors.magnetometer_ga[2] = imu.zmag; hil_sensors.magnetometer_range_ga = 32.7f; // int16 hil_sensors.magnetometer_mode = 0; // TODO what is this hil_sensors.magnetometer_cuttoff_freq_hz = 50.0f; hil_sensors.baro_pres_mbar = imu.abs_pressure; float tempC = imu.temperature; float tempAvgK = T0 + (tempC + ground_tempC) / 2.0f; float h = ground_alt + (R / g) * tempAvgK * logf(ground_press / imu.abs_pressure); hil_sensors.baro_alt_meter = h; hil_sensors.baro_temp_celcius = imu.temperature; /* publish */ orb_publish(ORB_ID(sensor_combined), pub_hil_sensors, &hil_sensors); // increment counters hil_counter += 1 ; hil_frames += 1 ; // output if ((timestamp - old_timestamp) > 10000000) { printf("receiving hil imu at %d hz\n", hil_frames/10); old_timestamp = timestamp; hil_frames = 0; } } if (msg->msgid == MAVLINK_MSG_ID_GPS_RAW_INT) { mavlink_gps_raw_int_t gps; mavlink_msg_gps_raw_int_decode(msg, &gps); /* packet counter */ static uint16_t hil_counter = 0; static uint16_t hil_frames = 0; static uint64_t old_timestamp = 0; /* gps */ hil_gps.timestamp_position = gps.time_usec; // hil_gps.counter = hil_counter++; hil_gps.time_gps_usec = gps.time_usec; hil_gps.lat = gps.lat; hil_gps.lon = gps.lon; hil_gps.alt = gps.alt; // hil_gps.counter_pos_valid = hil_counter++; hil_gps.eph_m = (float)gps.eph * 1e-2f; // from cm to m hil_gps.epv_m = (float)gps.epv * 1e-2f; // from cm to m hil_gps.s_variance_m_s = 100; // XXX 100 m/s variance? hil_gps.p_variance_m = 100; // XXX 100 m variance? hil_gps.vel_m_s = (float)gps.vel * 1e-2f; // from cm/s to m/s hil_gps.vel_n_m_s = (float)gps.vel * 1e-2f * cosf(gps.cog * M_DEG_TO_RAD_F * 1e-2f); hil_gps.vel_e_m_s = (float)gps.vel * 1e-2f * sinf(gps.cog * M_DEG_TO_RAD_F * 1e-2f); hil_gps.vel_d_m_s = 0.0f; hil_gps.cog_rad = gps.cog * M_DEG_TO_RAD_F * 1e-2f; // from deg*100 to rad hil_gps.fix_type = gps.fix_type; hil_gps.satellites_visible = gps.satellites_visible; /* publish */ orb_publish(ORB_ID(vehicle_gps_position), pub_hil_gps, &hil_gps); // increment counters hil_counter += 1 ; hil_frames += 1 ; // output if ((timestamp - old_timestamp) > 10000000) { printf("receiving hil gps at %d hz\n", hil_frames/10); old_timestamp = timestamp; hil_frames = 0; } } if (msg->msgid == MAVLINK_MSG_ID_RAW_PRESSURE) { mavlink_raw_pressure_t press; mavlink_msg_raw_pressure_decode(msg, &press); /* packet counter */ static uint16_t hil_counter = 0; static uint16_t hil_frames = 0; static uint64_t old_timestamp = 0; /* sensors general */ hil_sensors.timestamp = press.time_usec; /* baro */ float tempC = press.temperature / 100.0f; float tempAvgK = T0 + (tempC + ground_tempC) / 2.0f; float h = ground_alt + (R / g) * tempAvgK * logf(ground_press / press.press_abs); hil_sensors.baro_counter = hil_counter; hil_sensors.baro_pres_mbar = press.press_abs; hil_sensors.baro_alt_meter = h; hil_sensors.baro_temp_celcius = tempC; /* publish */ orb_publish(ORB_ID(sensor_combined), pub_hil_sensors, &hil_sensors); // increment counters hil_counter += 1 ; hil_frames += 1 ; // output if ((timestamp - old_timestamp) > 10000000) { printf("receiving hil pressure at %d hz\n", hil_frames/10); old_timestamp = timestamp; hil_frames = 0; } } if (msg->msgid == MAVLINK_MSG_ID_HIL_STATE) { mavlink_hil_state_t hil_state; mavlink_msg_hil_state_decode(msg, &hil_state); /* Calculate Rotation Matrix */ //TODO: better clarification which app does this, atm we have a ekf for quadrotors which does this, but there is no such thing if fly in fixed wing mode if (mavlink_system.type == MAV_TYPE_FIXED_WING) { //TODO: assuming low pitch and roll values for now hil_attitude.R[0][0] = cosf(hil_state.yaw); hil_attitude.R[0][1] = sinf(hil_state.yaw); hil_attitude.R[0][2] = 0.0f; hil_attitude.R[1][0] = -sinf(hil_state.yaw); hil_attitude.R[1][1] = cosf(hil_state.yaw); hil_attitude.R[1][2] = 0.0f; hil_attitude.R[2][0] = 0.0f; hil_attitude.R[2][1] = 0.0f; hil_attitude.R[2][2] = 1.0f; hil_attitude.R_valid = true; } hil_global_pos.lat = hil_state.lat; hil_global_pos.lon = hil_state.lon; hil_global_pos.alt = hil_state.alt / 1000.0f; hil_global_pos.vx = hil_state.vx / 100.0f; hil_global_pos.vy = hil_state.vy / 100.0f; hil_global_pos.vz = hil_state.vz / 100.0f; /* set timestamp and notify processes (broadcast) */ hil_global_pos.timestamp = hrt_absolute_time(); orb_publish(ORB_ID(vehicle_global_position), pub_hil_global_pos, &hil_global_pos); hil_attitude.roll = hil_state.roll; hil_attitude.pitch = hil_state.pitch; hil_attitude.yaw = hil_state.yaw; hil_attitude.rollspeed = hil_state.rollspeed; hil_attitude.pitchspeed = hil_state.pitchspeed; hil_attitude.yawspeed = hil_state.yawspeed; /* set timestamp and notify processes (broadcast) */ hil_attitude.timestamp = hrt_absolute_time(); orb_publish(ORB_ID(vehicle_attitude), pub_hil_attitude, &hil_attitude); } if (msg->msgid == MAVLINK_MSG_ID_MANUAL_CONTROL) { mavlink_manual_control_t man; mavlink_msg_manual_control_decode(msg, &man); struct rc_channels_s rc_hil; memset(&rc_hil, 0, sizeof(rc_hil)); static orb_advert_t rc_pub = 0; rc_hil.timestamp = hrt_absolute_time(); rc_hil.chan_count = 4; rc_hil.chan[0].scaled = man.x / 1000.0f; rc_hil.chan[1].scaled = man.y / 1000.0f; rc_hil.chan[2].scaled = man.r / 1000.0f; rc_hil.chan[3].scaled = man.z / 1000.0f; struct manual_control_setpoint_s mc; static orb_advert_t mc_pub = 0; int manual_sub = orb_subscribe(ORB_ID(manual_control_setpoint)); /* get a copy first, to prevent altering values that are not sent by the mavlink command */ orb_copy(ORB_ID(manual_control_setpoint), manual_sub, &mc); mc.timestamp = rc_hil.timestamp; mc.roll = man.x / 1000.0f; mc.pitch = man.y / 1000.0f; mc.yaw = man.r / 1000.0f; mc.throttle = man.z / 1000.0f; /* fake RC channels with manual control input from simulator */ if (rc_pub == 0) { rc_pub = orb_advertise(ORB_ID(rc_channels), &rc_hil); } else { orb_publish(ORB_ID(rc_channels), rc_pub, &rc_hil); } if (mc_pub == 0) { mc_pub = orb_advertise(ORB_ID(manual_control_setpoint), &mc); } else { orb_publish(ORB_ID(manual_control_setpoint), mc_pub, &mc); } } } }
void communication_receive(void) { mavlink_message_t msg; mavlink_status_t status; // COMMUNICATION THROUGH EXTERNAL UART PORT (XBee serial) while(cliPortAvailable()) { uint8_t c = cliPortRead(); // Try to get a new message if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) { // Handle message switch(msg.msgid) { //COMMANDS case MAVLINK_MSG_ID_COMMAND_LONG: { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(&msg, &cmd); switch (cmd.command) { /*CAMERA CONTROL COMMAND*/ case MAV_CMD_VIDEO_START_CAPTURE: /*Enable camera*/ cameraEnable(true); break; case MAV_CMD_VIDEO_STOP_CAPTURE: cameraEnable(false); break; case MAV_CMD_DO_DIGICAM_CONTROL: if (((int)(cmd.param1)) == 1){ cameraFlip(true); } else if (((int)(cmd.param1)) == 2){ cameraFlip(false); } else if (((int)(cmd.param3)) == 1){ cameraZoomIn(); } else if (((int)(cmd.param3)) == -1){ cameraZoomOut(); } else if (((int)(cmd.param3)) == 2){ cameraStopZoom(); } else if (((int)(cmd.param7)) == 1){ cameraEnableOSD(true); } else if (((int)(cmd.param7)) == -1){ cameraEnableOSD(false); } break; /*OSD CONTROL COMMAND ***UNCOMMENT WHEN THIS FUNCTIONALITY IS READY**** * case MAV_CMD_OSD_CONTROL: * if ((int)(cmd.param1)) == 0){ * //Disable component 1 * } * else if((int)(cmd.param1)) == 1){ * //Enable component 1 * } * if((int)(cmd.param2)) == 0){ * //Disable component 2 * } * else if((int)(cmd.param2)) == 0{ * //Enable component 2 * } * //Continue statements for each OSD component we wish to enable or disable * break; */ default: //mavlink_msg_command_ack_send(MAVLINK_COMM_0, cmd.command, MAV_RESULT_UNSUPPORTED); break; } } break; default: //Do nothing break; } } // And get the next one } // Update global packet drops counter packet_drops += status.packet_rx_drop_count; }
void handle_mavlink_message(mavlink_channel_t chan, mavlink_message_t* msg) { /* all messages from usart2 are directly forwarded */ if(chan == MAVLINK_COMM_1) { uint8_t buf[MAVLINK_MAX_PACKET_LEN]; uint32_t len; // Copy to USART 3 len = mavlink_msg_to_send_buffer(buf, msg); mavlink_send_uart_bytes(MAVLINK_COMM_0, buf, len); if(global_data.param[PARAM_USB_SEND_FORWARD]) mavlink_send_uart_bytes(MAVLINK_COMM_2, buf, len); return; } /* forwarded received messages from usb and usart3 to usart2 */ uint8_t buf[MAVLINK_MAX_PACKET_LEN]; uint32_t len; /* copy to usart2 */ len = mavlink_msg_to_send_buffer(buf, msg); for (int i = 0; i < len; i++) { usart2_tx_ringbuffer_push(buf, len); } /* handling messages */ switch (msg->msgid) { case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { mavlink_param_request_read_t set; mavlink_msg_param_request_read_decode(msg, &set); /* Check if this message is for this system */ if ((uint8_t) set.target_system == (uint8_t) global_data.param[PARAM_SYSTEM_ID] && (uint8_t) set.target_component == (uint8_t) global_data.param[PARAM_COMPONENT_ID]) { char* key = (char*) set.param_id; if (set.param_id[0] != -1) { /* Choose parameter based on index */ if ((set.param_index >= 0) && (set.param_index < ONBOARD_PARAM_COUNT)) { /* Report back value */ mavlink_msg_param_value_send(chan, global_data.param_name[set.param_index], global_data.param[set.param_index], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, set.param_index); } } else { for (int i = 0; i < ONBOARD_PARAM_COUNT; i++) { bool match = true; for (int j = 0; j < ONBOARD_PARAM_NAME_LENGTH; j++) { /* Compare */ if (((char) (global_data.param_name[i][j])) != (char) (key[j])) { match = false; } /* End matching if null termination is reached */ if (((char) global_data.param_name[i][j]) == '\0') { break; } } /* Check if matched */ if (match) { /* Report back value */ mavlink_msg_param_value_send(chan, global_data.param_name[i], global_data.param[i], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, i); } } } } } break; case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { /* Start sending parameters */ m_parameter_i = 0; } break; case MAVLINK_MSG_ID_PARAM_SET: { mavlink_param_set_t set; mavlink_msg_param_set_decode(msg, &set); /* Check if this message is for this system */ if ((uint8_t) set.target_system == (uint8_t) global_data.param[PARAM_SYSTEM_ID] && (uint8_t) set.target_component == (uint8_t) global_data.param[PARAM_COMPONENT_ID]) { char* key = (char*) set.param_id; for (int i = 0; i < ONBOARD_PARAM_COUNT; i++) { bool match = true; for (int j = 0; j < ONBOARD_PARAM_NAME_LENGTH; j++) { /* Compare */ if (((char) (global_data.param_name[i][j])) != (char) (key[j])) { match = false; } /* End matching if null termination is reached */ if (((char) global_data.param_name[i][j]) == '\0') { break; } } /* Check if matched */ if (match) { /* Only write and emit changes if there is actually a difference * AND only write if new value is NOT "not-a-number" * AND is NOT infinity */ if (global_data.param[i] != set.param_value && !isnan(set.param_value) && !isinf(set.param_value) && global_data.param_access[i]) { global_data.param[i] = set.param_value; /* handle sensor position */ if(i == PARAM_SENSOR_POSITION) { set_sensor_position_settings((uint8_t) set.param_value); mt9v034_context_configuration(); dma_reconfigure(); buffer_reset(); } /* handle low light mode and noise correction */ else if(i == PARAM_IMAGE_LOW_LIGHT || i == PARAM_IMAGE_ROW_NOISE_CORR|| i == PARAM_IMAGE_TEST_PATTERN) { mt9v034_context_configuration(); dma_reconfigure(); buffer_reset(); } /* handle calibration on/off */ else if(i == PARAM_VIDEO_ONLY) { mt9v034_set_context(); dma_reconfigure(); buffer_reset(); if(global_data.param[PARAM_VIDEO_ONLY]) debug_string_message_buffer("Calibration Mode On"); else debug_string_message_buffer("Calibration Mode Off"); } /* handle sensor position */ else if(i == PARAM_GYRO_SENSITIVITY_DPS) { l3gd20_config(); } else { debug_int_message_buffer("Parameter received, param id =", i); } /* report back new value */ mavlink_msg_param_value_send(MAVLINK_COMM_0, global_data.param_name[i], global_data.param[i], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, i); mavlink_msg_param_value_send(MAVLINK_COMM_2, global_data.param_name[i], global_data.param[i], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, i); } else { /* send back current value because it is not accepted or not write access*/ mavlink_msg_param_value_send(MAVLINK_COMM_0, global_data.param_name[i], global_data.param[i], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, i); mavlink_msg_param_value_send(MAVLINK_COMM_2, global_data.param_name[i], global_data.param[i], MAVLINK_TYPE_FLOAT, ONBOARD_PARAM_COUNT, i); } } } } } break; case MAVLINK_MSG_ID_PING: { mavlink_ping_t ping; mavlink_msg_ping_decode(msg, &ping); if (ping.target_system == 0 && ping.target_component == 0) { /* Respond to ping */ uint64_t r_timestamp = get_boot_time_us(); mavlink_msg_ping_send(chan, ping.seq, msg->sysid, msg->compid, r_timestamp); } } break; case MAVLINK_MSG_ID_COMMAND_LONG: { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(msg, &cmd); switch (cmd.command) { case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN: if (((int)(cmd.param1)) == 1) { mavlink_msg_command_ack_send(chan, cmd.command, MAV_RESULT_ACCEPTED); /* reboot */ systemreset(false); } else if (((int)(cmd.param1)) == 3) { mavlink_msg_command_ack_send(chan, cmd.command, MAV_RESULT_ACCEPTED); /* reboot to bootloader */ systemreset(true); } else { /* parameters are wrong */ mavlink_msg_command_ack_send(chan, cmd.command, MAV_RESULT_FAILED); // XXX add INVALID INPUT to MAV_RESULT } break; default: mavlink_msg_command_ack_send(chan, cmd.command, MAV_RESULT_UNSUPPORTED); break; } } break; default: break; } }
void MAVLinkCommandLong(mavlink_message_t* handle_msg) // MAVLINK_MSG_ID_COMMAND_LONG { mavlink_command_long_t packet; mavlink_msg_command_long_decode(handle_msg, &packet); DPRINT("MAVLINK_MSG_ID_COMMAND_LONG %u\r\n", handle_msg->msgid); //if (mavlink_check_target(packet.target, packet.target_component) == false) break; { switch (packet.command) { case MAV_CMD_PREFLIGHT_CALIBRATION: DPRINT("MAV_CMD_PREFLIGHT_CALIBRATION %u\r\n", packet.command); if (packet.param1 == 1) { #if (USE_NV_MEMORY ==1) udb_skip_flags.skip_imu_cal = 0; #endif // (USE_NV_MEMORY == 1) udb_a2d_record_offsets(); } else if (packet.param4 == 1) //param4 = radio calibration { if (udb_flags._.radio_on == 1) { udb_servo_record_trims(); command_ack(packet.command, MAV_CMD_ACK_OK); } else command_ack(packet.command, MAV_CMD_ACK_ERR_FAIL); } else command_ack(packet.command, MAV_CMD_ACK_ERR_NOT_SUPPORTED); break; #if (USE_NV_MEMORY == 1) case MAV_CMD_PREFLIGHT_STORAGE: DPRINT("MAV_CMD_PREFLIGHT_STORAGE %u\r\n", packet.command); if (packet.param1 == MAV_PFS_CMD_WRITE_ALL) // 1 { if (packet.param2 == MAV_PFS_CMD_WRITE_ALL) data_services_save_all(STORAGE_FLAG_STORE_CALIB | STORAGE_FLAG_STORE_WAYPOINTS, &preflight_storage_complete_callback); else data_services_save_all(STORAGE_FLAG_STORE_CALIB, &preflight_storage_complete_callback); } else if (packet.param1 == MAV_PFS_CMD_READ_ALL) // 0 { if (packet.param2 == MAV_PFS_CMD_READ_ALL) data_services_load_all(STORAGE_FLAG_STORE_CALIB | STORAGE_FLAG_STORE_WAYPOINTS, &preflight_storage_complete_callback); else data_services_load_all(STORAGE_FLAG_STORE_CALIB, &preflight_storage_complete_callback); } else command_ack(packet.command, MAV_CMD_ACK_ERR_NOT_SUPPORTED); break; case MAV_CMD_PREFLIGHT_STORAGE_ADVANCED: DPRINT("MAV_CMD_PREFLIGHT_STORAGE_ADVANCED %u\r\n", packet.command); switch ((uint16_t)packet.param1) { case MAV_PFS_CMD_CLEAR_SPECIFIC: storage_clear_area(packet.param2, &preflight_storage_complete_callback); break; case MAV_PFS_CMD_WRITE_SPECIFIC: data_services_save_specific(packet.param2, &preflight_storage_complete_callback); break; case MAV_PFS_CMD_READ_SPECIFIC: data_services_load_specific(packet.param2, &preflight_storage_complete_callback); break; default: command_ack(packet.command, MAV_CMD_ACK_ERR_NOT_SUPPORTED); break; } break; #endif // (USE_NV_MEMORY == 1) case 245: // MAV_CMD_PREFLIGHT_STORAGE: switch ((uint16_t)packet.param1) { case 0: // Read DPRINT("Read (ROM)\r\n"); config_load(); break; case 1: // Write DPRINT("Write (ROM)\r\n"); config_save(); break; default: DPRINT("245 packet.param1 %f packet.param2 %f\r\n", (double)packet.param1, (double)packet.param2); break; } break; case 246: // halt DPRINT("Halt - packet.command %u\r\n", packet.command); break; case 22: // start DPRINT("Start - packet.command %u\r\n", packet.command); break; case 252: // land DPRINT("Land - packet.command %u\r\n", packet.command); break; default: DPRINT("packet.command %u\r\n", packet.command); command_ack(packet.command, MAV_CMD_ACK_ERR_NOT_SUPPORTED); break; } } }
void mavlink_message_handler_receive(mavlink_message_handler_t* message_handler, mavlink_received_t* rec) { mavlink_message_t* msg = &rec->msg; if ( message_handler->debug ) { mavlink_message_handler_msg_default_dbg(msg); } if (msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { // The message is a command mavlink_command_long_t cmd; mavlink_msg_command_long_decode(msg, &cmd); //print packet command and parameters for debug print_util_dbg_print("target sysID:"); print_util_dbg_print_num(cmd.target_system,10); print_util_dbg_print(", target compID:"); print_util_dbg_print_num(cmd.target_component,10); print_util_dbg_print("\r\n"); print_util_dbg_print("parameters: "); print_util_dbg_print_num(cmd.param1,10); print_util_dbg_print_num(cmd.param2,10); print_util_dbg_print_num(cmd.param3,10); print_util_dbg_print_num(cmd.param4,10); print_util_dbg_print_num(cmd.param5,10); print_util_dbg_print_num(cmd.param6,10); print_util_dbg_print_num(cmd.param7,10); print_util_dbg_print("\r\n"); print_util_dbg_print("command id:"); print_util_dbg_print_num(cmd.command,10); print_util_dbg_print(", confirmation:"); print_util_dbg_print_num(cmd.confirmation,10); print_util_dbg_print("\r\n"); if (cmd.command >= 0 && cmd.command < MAV_CMD_ENUM_END) { // The command has valid command ID if( (cmd.target_system == message_handler->mavlink_stream->sysid)||(cmd.target_system == MAV_SYS_ID_ALL) ) { mav_result_t result = MAV_RESULT_UNSUPPORTED; // The command is for this system for (uint32_t i = 0; i < message_handler->cmd_callback_set->callback_count; ++i) { if ( match_cmd(message_handler, &message_handler->cmd_callback_set->callback_list[i], msg, &cmd) ) { mavlink_cmd_callback_function_t function = message_handler->cmd_callback_set->callback_list[i].function; handling_module_struct_t module_struct = message_handler->cmd_callback_set->callback_list[i].module_struct; // Call appropriate function callback result = function(module_struct, &cmd); break; } } // Send acknowledgment message mavlink_message_t msg; mavlink_msg_command_ack_pack( message_handler->mavlink_stream->sysid, message_handler->mavlink_stream->compid, &msg, cmd.command, result); mavlink_stream_send(message_handler->mavlink_stream, &msg); } } } else if ( msg->msgid >= 0 && msg->msgid < MAV_MSG_ENUM_END ) { // The message has a valid message ID, and is not a command for (uint32_t i = 0; i < message_handler->msg_callback_set->callback_count; ++i) { if ( match_msg(message_handler, &message_handler->msg_callback_set->callback_list[i], msg) ) { mavlink_msg_callback_function_t function = message_handler->msg_callback_set->callback_list[i].function; handling_module_struct_t module_struct = message_handler->msg_callback_set->callback_list[i].module_struct; uint32_t sys_id = *message_handler->msg_callback_set->callback_list[i].sys_id; // Call appropriate function callback function(module_struct, sys_id, msg); } } } }
void GCS_MAVLINK_Rover::handleMessage(mavlink_message_t* msg) { switch (msg->msgid) { case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: { handle_request_data_stream(msg, true); break; } case MAVLINK_MSG_ID_COMMAND_LONG: { // decode mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); uint8_t result = MAV_RESULT_UNSUPPORTED; // do command switch(packet.command) { case MAV_CMD_START_RX_PAIR: // initiate bind procedure if (!hal.rcin->rc_bind(packet.param1)) { result = MAV_RESULT_FAILED; } else { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_NAV_RETURN_TO_LAUNCH: rover.set_mode(RTL); result = MAV_RESULT_ACCEPTED; break; #if MOUNT == ENABLED // Sets the region of interest (ROI) for the camera case MAV_CMD_DO_SET_ROI: // sanity check location if (!check_latlng(packet.param5, packet.param6)) { break; } Location roi_loc; roi_loc.lat = (int32_t)(packet.param5 * 1.0e7f); roi_loc.lng = (int32_t)(packet.param6 * 1.0e7f); roi_loc.alt = (int32_t)(packet.param7 * 100.0f); if (roi_loc.lat == 0 && roi_loc.lng == 0 && roi_loc.alt == 0) { // switch off the camera tracking if enabled if (rover.camera_mount.get_mode() == MAV_MOUNT_MODE_GPS_POINT) { rover.camera_mount.set_mode_to_default(); } } else { // send the command to the camera mount rover.camera_mount.set_roi_target(roi_loc); } result = MAV_RESULT_ACCEPTED; break; #endif #if CAMERA == ENABLED case MAV_CMD_DO_DIGICAM_CONFIGURE: rover.camera.configure(packet.param1, packet.param2, packet.param3, packet.param4, packet.param5, packet.param6, packet.param7); result = MAV_RESULT_ACCEPTED; break; case MAV_CMD_DO_DIGICAM_CONTROL: if (rover.camera.control(packet.param1, packet.param2, packet.param3, packet.param4, packet.param5, packet.param6)) { rover.log_picture(); } result = MAV_RESULT_ACCEPTED; break; #endif // CAMERA == ENABLED case MAV_CMD_DO_MOUNT_CONTROL: #if MOUNT == ENABLED rover.camera_mount.control(packet.param1, packet.param2, packet.param3, (MAV_MOUNT_MODE) packet.param7); result = MAV_RESULT_ACCEPTED; #endif break; case MAV_CMD_MISSION_START: rover.set_mode(AUTO); result = MAV_RESULT_ACCEPTED; break; case MAV_CMD_PREFLIGHT_CALIBRATION: if(hal.util->get_soft_armed()) { result = MAV_RESULT_FAILED; break; } if (is_equal(packet.param1,1.0f)) { rover.ins.init_gyro(); if (rover.ins.gyro_calibrated_ok_all()) { rover.ahrs.reset_gyro_drift(); result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else if (is_equal(packet.param3,1.0f)) { rover.init_barometer(false); result = MAV_RESULT_ACCEPTED; } else if (is_equal(packet.param4,1.0f)) { rover.trim_radio(); result = MAV_RESULT_ACCEPTED; } else if (is_equal(packet.param5,1.0f)) { result = MAV_RESULT_ACCEPTED; // start with gyro calibration rover.ins.init_gyro(); // reset ahrs gyro bias if (rover.ins.gyro_calibrated_ok_all()) { rover.ahrs.reset_gyro_drift(); } else { result = MAV_RESULT_FAILED; } rover.ins.acal_init(); rover.ins.get_acal()->start(this); } else if (is_equal(packet.param5,2.0f)) { // start with gyro calibration rover.ins.init_gyro(); // accel trim float trim_roll, trim_pitch; if(rover.ins.calibrate_trim(trim_roll, trim_pitch)) { // reset ahrs's trim to suggested values from calibration routine rover.ahrs.set_trim(Vector3f(trim_roll, trim_pitch, 0)); result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else { send_text(MAV_SEVERITY_WARNING, "Unsupported preflight calibration"); } break; case MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS: { uint8_t compassNumber = -1; if (is_equal(packet.param1, 2.0f)) { compassNumber = 0; } else if (is_equal(packet.param1, 5.0f)) { compassNumber = 1; } else if (is_equal(packet.param1, 6.0f)) { compassNumber = 2; } if (compassNumber != (uint8_t) -1) { rover.compass.set_and_save_offsets(compassNumber, packet.param2, packet.param3, packet.param4); result = MAV_RESULT_ACCEPTED; } break; } case MAV_CMD_DO_SET_MODE: switch ((uint16_t)packet.param1) { case MAV_MODE_MANUAL_ARMED: case MAV_MODE_MANUAL_DISARMED: rover.set_mode(MANUAL); result = MAV_RESULT_ACCEPTED; break; case MAV_MODE_AUTO_ARMED: case MAV_MODE_AUTO_DISARMED: rover.set_mode(AUTO); result = MAV_RESULT_ACCEPTED; break; case MAV_MODE_STABILIZE_DISARMED: case MAV_MODE_STABILIZE_ARMED: rover.set_mode(LEARNING); result = MAV_RESULT_ACCEPTED; break; default: result = MAV_RESULT_UNSUPPORTED; } break; case MAV_CMD_DO_SET_SERVO: if (rover.ServoRelayEvents.do_set_servo(packet.param1, packet.param2)) { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_DO_REPEAT_SERVO: if (rover.ServoRelayEvents.do_repeat_servo(packet.param1, packet.param2, packet.param3, packet.param4*1000)) { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_DO_SET_RELAY: if (rover.ServoRelayEvents.do_set_relay(packet.param1, packet.param2)) { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_DO_REPEAT_RELAY: if (rover.ServoRelayEvents.do_repeat_relay(packet.param1, packet.param2, packet.param3*1000)) { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN: if (is_equal(packet.param1,1.0f) || is_equal(packet.param1,3.0f)) { // when packet.param1 == 3 we reboot to hold in bootloader hal.scheduler->reboot(is_equal(packet.param1,3.0f)); result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_COMPONENT_ARM_DISARM: if (is_equal(packet.param1,1.0f)) { // run pre_arm_checks and arm_checks and display failures if (rover.arm_motors(AP_Arming::MAVLINK)) { result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else if (is_zero(packet.param1)) { if (rover.disarm_motors()) { result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else { result = MAV_RESULT_UNSUPPORTED; } break; case MAV_CMD_GET_HOME_POSITION: if (rover.home_is_set != HOME_UNSET) { send_home(rover.ahrs.get_home()); result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES: { if (is_equal(packet.param1,1.0f)) { send_autopilot_version(FIRMWARE_VERSION); result = MAV_RESULT_ACCEPTED; } break; } case MAV_CMD_DO_SET_HOME: { // param1 : use current (1=use current location, 0=use specified location) // param5 : latitude // param6 : longitude // param7 : altitude result = MAV_RESULT_FAILED; // assume failure if (is_equal(packet.param1,1.0f)) { rover.init_home(); } else { if (is_zero(packet.param5) && is_zero(packet.param6) && is_zero(packet.param7)) { // don't allow the 0,0 position break; } // sanity check location if (!check_latlng(packet.param5, packet.param6)) { break; } Location new_home_loc {}; new_home_loc.lat = (int32_t)(packet.param5 * 1.0e7f); new_home_loc.lng = (int32_t)(packet.param6 * 1.0e7f); new_home_loc.alt = (int32_t)(packet.param7 * 100.0f); rover.ahrs.set_home(new_home_loc); rover.home_is_set = HOME_SET_NOT_LOCKED; rover.Log_Write_Home_And_Origin(); GCS_MAVLINK::send_home_all(new_home_loc); result = MAV_RESULT_ACCEPTED; rover.gcs_send_text_fmt(MAV_SEVERITY_INFO, "Set HOME to %.6f %.6f at %um", (double)(new_home_loc.lat*1.0e-7f), (double)(new_home_loc.lng*1.0e-7f), (uint32_t)(new_home_loc.alt*0.01f)); } break; } case MAV_CMD_DO_START_MAG_CAL: case MAV_CMD_DO_ACCEPT_MAG_CAL: case MAV_CMD_DO_CANCEL_MAG_CAL: result = rover.compass.handle_mag_cal_command(packet); break; default: break; } mavlink_msg_command_ack_send_buf( msg, chan, packet.command, result); break; } case MAVLINK_MSG_ID_SET_MODE: { handle_set_mode(msg, FUNCTOR_BIND(&rover, &Rover::mavlink_set_mode, bool, uint8_t)); break; } case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: { handle_mission_request_list(rover.mission, msg); break; } // XXX read a WP from EEPROM and send it to the GCS case MAVLINK_MSG_ID_MISSION_REQUEST_INT: case MAVLINK_MSG_ID_MISSION_REQUEST: { handle_mission_request(rover.mission, msg); break; } case MAVLINK_MSG_ID_MISSION_ACK: { // not used break; } case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { // mark the firmware version in the tlog send_text(MAV_SEVERITY_INFO, FIRMWARE_STRING); #if defined(PX4_GIT_VERSION) && defined(NUTTX_GIT_VERSION) send_text(MAV_SEVERITY_INFO, "PX4: " PX4_GIT_VERSION " NuttX: " NUTTX_GIT_VERSION); #endif handle_param_request_list(msg); break; } case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { handle_param_request_read(msg); break; } case MAVLINK_MSG_ID_MISSION_CLEAR_ALL: { handle_mission_clear_all(rover.mission, msg); break; } case MAVLINK_MSG_ID_MISSION_SET_CURRENT: { handle_mission_set_current(rover.mission, msg); break; } case MAVLINK_MSG_ID_MISSION_COUNT: { handle_mission_count(rover.mission, msg); break; } case MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST: { handle_mission_write_partial_list(rover.mission, msg); break; } // GCS has sent us a mission item, store to EEPROM case MAVLINK_MSG_ID_MISSION_ITEM: { if (handle_mission_item(msg, rover.mission)) { rover.DataFlash.Log_Write_EntireMission(rover.mission); } break; } case MAVLINK_MSG_ID_MISSION_ITEM_INT: { if (handle_mission_item(msg, rover.mission)) { rover.DataFlash.Log_Write_EntireMission(rover.mission); } break; } case MAVLINK_MSG_ID_PARAM_SET: { handle_param_set(msg, &rover.DataFlash); break; } case MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE: { // allow override of RC channel values for HIL // or for complete GCS control of switch position // and RC PWM values. if(msg->sysid != rover.g.sysid_my_gcs) break; // Only accept control from our gcs mavlink_rc_channels_override_t packet; int16_t v[8]; mavlink_msg_rc_channels_override_decode(msg, &packet); v[0] = packet.chan1_raw; v[1] = packet.chan2_raw; v[2] = packet.chan3_raw; v[3] = packet.chan4_raw; v[4] = packet.chan5_raw; v[5] = packet.chan6_raw; v[6] = packet.chan7_raw; v[7] = packet.chan8_raw; hal.rcin->set_overrides(v, 8); rover.failsafe.rc_override_timer = AP_HAL::millis(); rover.failsafe_trigger(FAILSAFE_EVENT_RC, false); break; } case MAVLINK_MSG_ID_HEARTBEAT: { // We keep track of the last time we received a heartbeat from our GCS for failsafe purposes if(msg->sysid != rover.g.sysid_my_gcs) break; rover.last_heartbeat_ms = rover.failsafe.rc_override_timer = AP_HAL::millis(); rover.failsafe_trigger(FAILSAFE_EVENT_GCS, false); break; } case MAVLINK_MSG_ID_GPS_INPUT: { rover.gps.handle_msg(msg); break; } #if HIL_MODE != HIL_MODE_DISABLED case MAVLINK_MSG_ID_HIL_STATE: { mavlink_hil_state_t packet; mavlink_msg_hil_state_decode(msg, &packet); // sanity check location if (!check_latlng(packet.lat, packet.lon)) { break; } // set gps hil sensor Location loc; loc.lat = packet.lat; loc.lng = packet.lon; loc.alt = packet.alt/10; Vector3f vel(packet.vx, packet.vy, packet.vz); vel *= 0.01f; gps.setHIL(0, AP_GPS::GPS_OK_FIX_3D, packet.time_usec/1000, loc, vel, 10, 0); // rad/sec Vector3f gyros; gyros.x = packet.rollspeed; gyros.y = packet.pitchspeed; gyros.z = packet.yawspeed; // m/s/s Vector3f accels; accels.x = packet.xacc * (GRAVITY_MSS/1000.0f); accels.y = packet.yacc * (GRAVITY_MSS/1000.0f); accels.z = packet.zacc * (GRAVITY_MSS/1000.0f); ins.set_gyro(0, gyros); ins.set_accel(0, accels); compass.setHIL(0, packet.roll, packet.pitch, packet.yaw); compass.setHIL(1, packet.roll, packet.pitch, packet.yaw); break; } #endif // HIL_MODE #if CAMERA == ENABLED //deprecated. Use MAV_CMD_DO_DIGICAM_CONFIGURE case MAVLINK_MSG_ID_DIGICAM_CONFIGURE: { break; } //deprecated. Use MAV_CMD_DO_DIGICAM_CONFIGURE case MAVLINK_MSG_ID_DIGICAM_CONTROL: { rover.camera.control_msg(msg); rover.log_picture(); break; } #endif // CAMERA == ENABLED #if MOUNT == ENABLED //deprecated. Use MAV_CMD_DO_MOUNT_CONFIGURE case MAVLINK_MSG_ID_MOUNT_CONFIGURE: { rover.camera_mount.configure_msg(msg); break; } //deprecated. Use MAV_CMD_DO_MOUNT_CONTROL case MAVLINK_MSG_ID_MOUNT_CONTROL: { rover.camera_mount.control_msg(msg); break; } #endif // MOUNT == ENABLED case MAVLINK_MSG_ID_RADIO: case MAVLINK_MSG_ID_RADIO_STATUS: { handle_radio_status(msg, rover.DataFlash, rover.should_log(MASK_LOG_PM)); break; } case MAVLINK_MSG_ID_LOG_REQUEST_DATA: case MAVLINK_MSG_ID_LOG_ERASE: rover.in_log_download = true; /* no break */ case MAVLINK_MSG_ID_LOG_REQUEST_LIST: if (!rover.in_mavlink_delay) { handle_log_message(msg, rover.DataFlash); } break; case MAVLINK_MSG_ID_LOG_REQUEST_END: rover.in_log_download = false; if (!rover.in_mavlink_delay) { handle_log_message(msg, rover.DataFlash); } break; case MAVLINK_MSG_ID_SERIAL_CONTROL: handle_serial_control(msg, rover.gps); break; case MAVLINK_MSG_ID_GPS_INJECT_DATA: handle_gps_inject(msg, rover.gps); break; case MAVLINK_MSG_ID_DISTANCE_SENSOR: rover.sonar.handle_msg(msg); break; case MAVLINK_MSG_ID_REMOTE_LOG_BLOCK_STATUS: rover.DataFlash.remote_log_block_status_msg(chan, msg); break; case MAVLINK_MSG_ID_AUTOPILOT_VERSION_REQUEST: send_autopilot_version(FIRMWARE_VERSION); break; case MAVLINK_MSG_ID_SETUP_SIGNING: handle_setup_signing(msg); break; case MAVLINK_MSG_ID_LED_CONTROL: // send message to Notify AP_Notify::handle_led_control(msg); break; case MAVLINK_MSG_ID_PLAY_TUNE: // send message to Notify AP_Notify::handle_play_tune(msg); break; } // end switch } // end handle mavlink
/**************************************************************************** * Public Functions ****************************************************************************/ void handleMessage(mavlink_message_t * msg) { //check for terminate command if(msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG) { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(msg, &cmd); if (cmd.target_system == mavlink_system.sysid && ((cmd.target_component == mavlink_system.compid) || (cmd.target_component == MAV_COMP_ID_ALL))) { bool terminate_link = false; bool reboot = false; /* result of the command */ uint8_t result = MAV_RESULT_UNSUPPORTED; /* supported command handling start */ /* request to set different system mode */ if (cmd.command == MAV_CMD_DO_SET_MODE) { mavlink_system.mode = cmd.param1; } /* request to arm */ // XXX /* request for an autopilot reboot */ if (cmd.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && cmd.param1 == 1.0f) { reboot = true; result = MAV_RESULT_ACCEPTED; mavlink_msg_statustext_send(chan,0,"Rebooting autopilot.. "); } /* request for a link shutdown */ if (cmd.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && cmd.param1 == 3.0f) { terminate_link = true; result = MAV_RESULT_ACCEPTED; mavlink_msg_statustext_send(chan,0,"Terminating MAVLink.. "); } /* supported command handling stop */ /* send any requested ACKs */ if (cmd.confirmation > 0) { mavlink_msg_command_ack_send(chan, cmd.command, result); } /* the two termination / reset commands need special handling */ if (terminate_link) { printf("MAVLink: Terminating.. \n"); fflush(stdout); /* sleep 100 ms to allow UART buffer to empty */ led_off(LED_BLUE); led_on(LED_AMBER); int i; for (i = 0; i < 5; i++) { led_toggle(LED_AMBER); usleep(20000); } //terminate other threads: pthread_cancel(heartbeat_thread); //terminate this thread (receive_thread) pthread_exit(NULL); } if (reboot) { printf("MAVLink: Rebooting system.. \n"); fflush(stdout); /* sleep 100 ms to allow UART buffer to empty */ led_off(LED_BLUE); led_on(LED_AMBER); int i; for (i = 0; i < 5; i++) { led_toggle(LED_BLUE); led_toggle(LED_AMBER); usleep(20000); } //terminate other threads: pthread_cancel(heartbeat_thread); // Reset whole system /* Resetting CPU */ // FIXME Need check for ARM architecture here #ifndef NVIC_AIRCR #define NVIC_AIRCR (*((uint32_t*)0xE000ED0C)) #endif /* Set the SYSRESETREQ bit to force a reset */ NVIC_AIRCR = 0x05fa0004; /* Spinning until the board is really reset */ while(true); } } } /* Handle quadrotor motor setpoints */ if(msg->msgid == MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT) { mavlink_set_quad_motors_setpoint_t quad_motors_setpoint; mavlink_msg_set_quad_motors_setpoint_decode(msg, &quad_motors_setpoint); if(quad_motors_setpoint.target_system == mavlink_system.sysid) { global_data_lock(&global_data_quad_motors_setpoint.access_conf); global_data_quad_motors_setpoint.motor_front_nw = quad_motors_setpoint.motor_front_nw; global_data_quad_motors_setpoint.motor_right_ne = quad_motors_setpoint.motor_right_ne; global_data_quad_motors_setpoint.motor_back_se = quad_motors_setpoint.motor_back_se; global_data_quad_motors_setpoint.motor_left_sw = quad_motors_setpoint.motor_left_sw; global_data_quad_motors_setpoint.counter++; global_data_quad_motors_setpoint.timestamp = global_data_get_timestamp_milliseconds(); global_data_unlock(&global_data_quad_motors_setpoint.access_conf); /* Inform the other processes that there is new gps data available */ global_data_broadcast(&global_data_quad_motors_setpoint.access_conf); } } }
void mavlink_common_message_handler(const mavlink_message_t *msg) { switch (msg->msgid) { case MAVLINK_MSG_ID_HEARTBEAT: break; /* When requesting data streams say we can't send them */ case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: { mavlink_request_data_stream_t cmd; mavlink_msg_request_data_stream_decode(msg, &cmd); mavlink_msg_data_stream_send(MAVLINK_COMM_0, cmd.req_stream_id, 0, 0); MAVLinkSendMessage(); break; } /* Override channels with RC */ case MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE: { mavlink_rc_channels_override_t cmd; mavlink_msg_rc_channels_override_decode(msg, &cmd); #if defined RADIO_CONTROL && defined RADIO_CONTROL_TYPE_DATALINK uint8_t thrust = (cmd.chan3_raw - 950) * 127 / 1100; int8_t roll = -(cmd.chan1_raw - 1500) * 255 / 1100 / 2; int8_t pitch = -(cmd.chan2_raw - 1500) * 255 / 1100 / 2; int8_t yaw = -(cmd.chan4_raw - 1500) * 255 / 1100; parse_rc_4ch_datalink(0, thrust, roll, pitch, yaw); //printf("RECEIVED: RC Channel Override for: %d/%d: throttle: %d; roll: %d; pitch: %d; yaw: %d;\r\n", // cmd.target_system, cmd.target_component, thrust, roll, pitch, yaw); #endif break; } /* When a request is made of the parameters list */ case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: { mavlink_params_idx = 0; break; } /* When a request os made for a specific parameter */ case MAVLINK_MSG_ID_PARAM_REQUEST_READ: { mavlink_param_request_read_t cmd; mavlink_msg_param_request_read_decode(msg, &cmd); // First check param_index and search for the ID if needed if (cmd.param_index == -1) { cmd.param_index = settings_idx_from_param_id(cmd.param_id); } // Send message only if the param_index was found (Coverity Scan) if (cmd.param_index > -1) { mavlink_msg_param_value_send(MAVLINK_COMM_0, mavlink_param_names[cmd.param_index], settings_get_value(cmd.param_index), MAV_PARAM_TYPE_REAL32, NB_SETTING, cmd.param_index); MAVLinkSendMessage(); } break; } case MAVLINK_MSG_ID_PARAM_SET: { mavlink_param_set_t set; mavlink_msg_param_set_decode(msg, &set); // Check if this message is for this system if ((uint8_t) set.target_system == AC_ID) { int16_t idx = settings_idx_from_param_id(set.param_id); // setting found if (idx >= 0) { // Only write if new value is NOT "not-a-number" // AND is NOT infinity if (set.param_type == MAV_PARAM_TYPE_REAL32 && !isnan(set.param_value) && !isinf(set.param_value)) { DlSetting(idx, set.param_value); // Report back new value mavlink_msg_param_value_send(MAVLINK_COMM_0, mavlink_param_names[idx], settings_get_value(idx), MAV_PARAM_TYPE_REAL32, NB_SETTING, idx); MAVLinkSendMessage(); } } } } break; #ifndef AP /* only for rotorcraft */ case MAVLINK_MSG_ID_COMMAND_LONG: { mavlink_command_long_t cmd; mavlink_msg_command_long_decode(msg, &cmd); // Check if this message is for this system if ((uint8_t) cmd.target_system == AC_ID) { uint8_t result = MAV_RESULT_UNSUPPORTED; switch (cmd.command) { case MAV_CMD_NAV_GUIDED_ENABLE: MAVLINK_DEBUG("got cmd NAV_GUIDED_ENABLE: %f\n", cmd.param1); result = MAV_RESULT_FAILED; if (cmd.param1 > 0.5) { autopilot_set_mode(AP_MODE_GUIDED); if (autopilot_mode == AP_MODE_GUIDED) { result = MAV_RESULT_ACCEPTED; } } else { // turn guided mode off - to what? maybe NAV? or MODE_AUTO2? } break; case MAV_CMD_COMPONENT_ARM_DISARM: /* supposed to use this command to arm or SET_MODE?? */ MAVLINK_DEBUG("got cmd COMPONENT_ARM_DISARM: %f\n", cmd.param1); result = MAV_RESULT_FAILED; if (cmd.param1 > 0.5) { autopilot_set_motors_on(TRUE); if (autopilot_motors_on) result = MAV_RESULT_ACCEPTED; } else { autopilot_set_motors_on(FALSE); if (!autopilot_motors_on) result = MAV_RESULT_ACCEPTED; } break; default: break; } // confirm command with result mavlink_msg_command_ack_send(MAVLINK_COMM_0, cmd.command, result); MAVLinkSendMessage(); } break; } case MAVLINK_MSG_ID_SET_MODE: { mavlink_set_mode_t mode; mavlink_msg_set_mode_decode(msg, &mode); if (mode.target_system == AC_ID) { MAVLINK_DEBUG("got SET_MODE: base_mode:%d\n", mode.base_mode); if (mode.base_mode & MAV_MODE_FLAG_SAFETY_ARMED) { autopilot_set_motors_on(TRUE); } else { autopilot_set_motors_on(FALSE); } if (mode.base_mode & MAV_MODE_FLAG_GUIDED_ENABLED) { autopilot_set_mode(AP_MODE_GUIDED); } else if (mode.base_mode & MAV_MODE_FLAG_AUTO_ENABLED) { autopilot_set_mode(AP_MODE_NAV); } } break; } case MAVLINK_MSG_ID_SET_POSITION_TARGET_LOCAL_NED: { mavlink_set_position_target_local_ned_t target; mavlink_msg_set_position_target_local_ned_decode(msg, &target); // Check if this message is for this system if (target.target_system == AC_ID) { MAVLINK_DEBUG("SET_POSITION_TARGET_LOCAL_NED, byte_mask: %d\n", target.type_mask); /* if position and yaw bits are not set to ignored, use only position for now */ if (!(target.type_mask & 0b1110000000100000)) { switch (target.coordinate_frame) { case MAV_FRAME_LOCAL_NED: MAVLINK_DEBUG("set position target, frame LOCAL_NED\n"); autopilot_guided_goto_ned(target.x, target.y, target.z, target.yaw); break; case MAV_FRAME_LOCAL_OFFSET_NED: MAVLINK_DEBUG("set position target, frame LOCAL_OFFSET_NED\n"); autopilot_guided_goto_ned_relative(target.x, target.y, target.z, target.yaw); break; case MAV_FRAME_BODY_OFFSET_NED: MAVLINK_DEBUG("set position target, frame BODY_OFFSET_NED\n"); autopilot_guided_goto_body_relative(target.x, target.y, target.z, target.yaw); break; default: break; } } else if (!(target.type_mask & 0b0001110000100000)) { /* position is set to ignore, but velocity not */ switch (target.coordinate_frame) { case MAV_FRAME_LOCAL_NED: MAVLINK_DEBUG("set velocity target, frame LOCAL_NED\n"); autopilot_guided_move_ned(target.vx, target.vy, target.vz, target.yaw); break; default: break; } } } break; } #endif default: //Do nothing MAVLINK_DEBUG("Received message with id: %d\r\n", msg->msgid); break; } }
void GCS_MAVLINK_Rover::handleMessage(mavlink_message_t* msg) { switch (msg->msgid) { case MAVLINK_MSG_ID_REQUEST_DATA_STREAM: { handle_request_data_stream(msg, true); break; } case MAVLINK_MSG_ID_COMMAND_INT: { // decode packet mavlink_command_int_t packet; mavlink_msg_command_int_decode(msg, &packet); MAV_RESULT result = MAV_RESULT_UNSUPPORTED; switch (packet.command) { case MAV_CMD_DO_SET_HOME: { // assume failure result = MAV_RESULT_FAILED; if (is_equal(packet.param1, 1.0f)) { // if param1 is 1, use current location if (rover.set_home_to_current_location(true)) { result = MAV_RESULT_ACCEPTED; } break; } // ensure param1 is zero if (!is_zero(packet.param1)) { break; } // check frame type is supported if (packet.frame != MAV_FRAME_GLOBAL && packet.frame != MAV_FRAME_GLOBAL_INT && packet.frame != MAV_FRAME_GLOBAL_RELATIVE_ALT && packet.frame != MAV_FRAME_GLOBAL_RELATIVE_ALT_INT) { break; } // sanity check location if (!check_latlng(packet.x, packet.y)) { break; } Location new_home_loc {}; new_home_loc.lat = packet.x; new_home_loc.lng = packet.y; new_home_loc.alt = packet.z * 100; // handle relative altitude if (packet.frame == MAV_FRAME_GLOBAL_RELATIVE_ALT || packet.frame == MAV_FRAME_GLOBAL_RELATIVE_ALT_INT) { if (!rover.ahrs.home_is_set()) { // cannot use relative altitude if home is not set break; } new_home_loc.alt += rover.ahrs.get_home().alt; } if (rover.set_home(new_home_loc, true)) { result = MAV_RESULT_ACCEPTED; } break; } #if MOUNT == ENABLED case MAV_CMD_DO_SET_ROI: { // param1 : /* Region of interest mode (not used)*/ // param2 : /* MISSION index/ target ID (not used)*/ // param3 : /* ROI index (not used)*/ // param4 : /* empty */ // x : lat // y : lon // z : alt // sanity check location if (!check_latlng(packet.x, packet.y)) { break; } Location roi_loc; roi_loc.lat = packet.x; roi_loc.lng = packet.y; roi_loc.alt = (int32_t)(packet.z * 100.0f); if (roi_loc.lat == 0 && roi_loc.lng == 0 && roi_loc.alt == 0) { // switch off the camera tracking if enabled if (rover.camera_mount.get_mode() == MAV_MOUNT_MODE_GPS_POINT) { rover.camera_mount.set_mode_to_default(); } } else { // send the command to the camera mount rover.camera_mount.set_roi_target(roi_loc); } result = MAV_RESULT_ACCEPTED; break; } #endif default: result = MAV_RESULT_UNSUPPORTED; break; } // send ACK or NAK mavlink_msg_command_ack_send_buf(msg, chan, packet.command, result); break; } case MAVLINK_MSG_ID_COMMAND_LONG: { // decode mavlink_command_long_t packet; mavlink_msg_command_long_decode(msg, &packet); MAV_RESULT result = MAV_RESULT_UNSUPPORTED; // do command switch (packet.command) { case MAV_CMD_NAV_RETURN_TO_LAUNCH: rover.set_mode(rover.mode_rtl, MODE_REASON_GCS_COMMAND); result = MAV_RESULT_ACCEPTED; break; #if MOUNT == ENABLED // Sets the region of interest (ROI) for the camera case MAV_CMD_DO_SET_ROI: // sanity check location if (!check_latlng(packet.param5, packet.param6)) { break; } Location roi_loc; roi_loc.lat = (int32_t)(packet.param5 * 1.0e7f); roi_loc.lng = (int32_t)(packet.param6 * 1.0e7f); roi_loc.alt = (int32_t)(packet.param7 * 100.0f); if (roi_loc.lat == 0 && roi_loc.lng == 0 && roi_loc.alt == 0) { // switch off the camera tracking if enabled if (rover.camera_mount.get_mode() == MAV_MOUNT_MODE_GPS_POINT) { rover.camera_mount.set_mode_to_default(); } } else { // send the command to the camera mount rover.camera_mount.set_roi_target(roi_loc); } result = MAV_RESULT_ACCEPTED; break; #endif case MAV_CMD_DO_MOUNT_CONTROL: #if MOUNT == ENABLED rover.camera_mount.control(packet.param1, packet.param2, packet.param3, (MAV_MOUNT_MODE) packet.param7); result = MAV_RESULT_ACCEPTED; #endif break; case MAV_CMD_MISSION_START: rover.set_mode(rover.mode_auto, MODE_REASON_GCS_COMMAND); result = MAV_RESULT_ACCEPTED; break; case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN: if (is_equal(packet.param1, 1.0f) || is_equal(packet.param1, 3.0f)) { // when packet.param1 == 3 we reboot to hold in bootloader hal.scheduler->reboot(is_equal(packet.param1, 3.0f)); result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_COMPONENT_ARM_DISARM: if (is_equal(packet.param1, 1.0f)) { // run pre_arm_checks and arm_checks and display failures if (rover.arm_motors(AP_Arming::MAVLINK)) { result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else if (is_zero(packet.param1)) { if (rover.disarm_motors()) { result = MAV_RESULT_ACCEPTED; } else { result = MAV_RESULT_FAILED; } } else { result = MAV_RESULT_UNSUPPORTED; } break; case MAV_CMD_DO_FENCE_ENABLE: result = MAV_RESULT_ACCEPTED; switch ((uint16_t)packet.param1) { case 0: rover.g2.fence.enable(false); break; case 1: rover.g2.fence.enable(true); break; default: result = MAV_RESULT_FAILED; break; } break; case MAV_CMD_DO_SET_HOME: { // param1 : use current (1=use current location, 0=use specified location) // param5 : latitude // param6 : longitude // param7 : altitude result = MAV_RESULT_FAILED; // assume failure if (is_equal(packet.param1, 1.0f)) { if (rover.set_home_to_current_location(true)) { result = MAV_RESULT_ACCEPTED; } } else { // ensure param1 is zero if (!is_zero(packet.param1)) { break; } Location new_home_loc {}; new_home_loc.lat = static_cast<int32_t>(packet.param5 * 1.0e7f); new_home_loc.lng = static_cast<int32_t>(packet.param6 * 1.0e7f); new_home_loc.alt = static_cast<int32_t>(packet.param7 * 100.0f); if (rover.set_home(new_home_loc, true)) { result = MAV_RESULT_ACCEPTED; } } break; } case MAV_CMD_NAV_SET_YAW_SPEED: { // param1 : yaw angle to adjust direction by in centidegress // param2 : Speed - normalized to 0 .. 1 // exit if vehicle is not in Guided mode if (rover.control_mode != &rover.mode_guided) { break; } // send yaw change and target speed to guided mode controller const float speed_max = rover.control_mode->get_speed_default(); const float target_speed = constrain_float(packet.param2 * speed_max, -speed_max, speed_max); rover.mode_guided.set_desired_heading_delta_and_speed(packet.param1, target_speed); result = MAV_RESULT_ACCEPTED; break; } case MAV_CMD_ACCELCAL_VEHICLE_POS: result = MAV_RESULT_FAILED; if (rover.ins.get_acal()->gcs_vehicle_position(packet.param1)) { result = MAV_RESULT_ACCEPTED; } break; case MAV_CMD_DO_MOTOR_TEST: // param1 : motor sequence number (a number from 1 to max number of motors on the vehicle) // param2 : throttle type (0=throttle percentage, 1=PWM, 2=pilot throttle channel pass-through. See MOTOR_TEST_THROTTLE_TYPE enum) // param3 : throttle (range depends upon param2) // param4 : timeout (in seconds) result = rover.mavlink_motor_test_start(chan, static_cast<uint8_t>(packet.param1), static_cast<uint8_t>(packet.param2), static_cast<int16_t>(packet.param3), packet.param4); break; default: result = handle_command_long_message(packet); break; } mavlink_msg_command_ack_send_buf( msg, chan, packet.command, result); break; } case MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE: { // allow override of RC channel values for HIL // or for complete GCS control of switch position // and RC PWM values. if (msg->sysid != rover.g.sysid_my_gcs) { // Only accept control from our gcs break; } mavlink_rc_channels_override_t packet; mavlink_msg_rc_channels_override_decode(msg, &packet); RC_Channels::set_override(0, packet.chan1_raw); RC_Channels::set_override(1, packet.chan2_raw); RC_Channels::set_override(2, packet.chan3_raw); RC_Channels::set_override(3, packet.chan4_raw); RC_Channels::set_override(4, packet.chan5_raw); RC_Channels::set_override(5, packet.chan6_raw); RC_Channels::set_override(6, packet.chan7_raw); RC_Channels::set_override(7, packet.chan8_raw); rover.failsafe.rc_override_timer = AP_HAL::millis(); rover.failsafe_trigger(FAILSAFE_EVENT_RC, false); break; } case MAVLINK_MSG_ID_MANUAL_CONTROL: { if (msg->sysid != rover.g.sysid_my_gcs) { // Only accept control from our gcs break; } mavlink_manual_control_t packet; mavlink_msg_manual_control_decode(msg, &packet); if (packet.target != rover.g.sysid_this_mav) { break; // only accept control aimed at us } const int16_t roll = (packet.y == INT16_MAX) ? 0 : rover.channel_steer->get_radio_min() + (rover.channel_steer->get_radio_max() - rover.channel_steer->get_radio_min()) * (packet.y + 1000) / 2000.0f; const int16_t throttle = (packet.z == INT16_MAX) ? 0 : rover.channel_throttle->get_radio_min() + (rover.channel_throttle->get_radio_max() - rover.channel_throttle->get_radio_min()) * (packet.z + 1000) / 2000.0f; RC_Channels::set_override(uint8_t(rover.rcmap.roll() - 1), roll); RC_Channels::set_override(uint8_t(rover.rcmap.throttle() - 1), throttle); rover.failsafe.rc_override_timer = AP_HAL::millis(); rover.failsafe_trigger(FAILSAFE_EVENT_RC, false); break; } case MAVLINK_MSG_ID_HEARTBEAT: { // We keep track of the last time we received a heartbeat from our GCS for failsafe purposes if (msg->sysid != rover.g.sysid_my_gcs) { break; } rover.last_heartbeat_ms = rover.failsafe.rc_override_timer = AP_HAL::millis(); rover.failsafe_trigger(FAILSAFE_EVENT_GCS, false); break; } case MAVLINK_MSG_ID_SET_ATTITUDE_TARGET: // MAV ID: 82 { // decode packet mavlink_set_attitude_target_t packet; mavlink_msg_set_attitude_target_decode(msg, &packet); // exit if vehicle is not in Guided mode if (rover.control_mode != &rover.mode_guided) { break; } // ensure type_mask specifies to use thrust if ((packet.type_mask & MAVLINK_SET_ATT_TYPE_MASK_THROTTLE_IGNORE) != 0) { break; } // convert thrust to ground speed packet.thrust = constrain_float(packet.thrust, -1.0f, 1.0f); const float target_speed = rover.control_mode->get_speed_default() * packet.thrust; // if the body_yaw_rate field is ignored, convert quaternion to heading if ((packet.type_mask & MAVLINK_SET_ATT_TYPE_MASK_YAW_RATE_IGNORE) != 0) { // convert quaternion to heading float target_heading_cd = degrees(Quaternion(packet.q[0], packet.q[1], packet.q[2], packet.q[3]).get_euler_yaw()) * 100.0f; rover.mode_guided.set_desired_heading_and_speed(target_heading_cd, target_speed); } else { // use body_yaw_rate field rover.mode_guided.set_desired_turn_rate_and_speed((RAD_TO_DEG * packet.body_yaw_rate) * 100.0f, target_speed); } break; } case MAVLINK_MSG_ID_SET_POSITION_TARGET_LOCAL_NED: // MAV ID: 84 { // decode packet mavlink_set_position_target_local_ned_t packet; mavlink_msg_set_position_target_local_ned_decode(msg, &packet); // exit if vehicle is not in Guided mode if (rover.control_mode != &rover.mode_guided) { break; } // check for supported coordinate frames if (packet.coordinate_frame != MAV_FRAME_LOCAL_NED && packet.coordinate_frame != MAV_FRAME_LOCAL_OFFSET_NED && packet.coordinate_frame != MAV_FRAME_BODY_NED && packet.coordinate_frame != MAV_FRAME_BODY_OFFSET_NED) { break; } bool pos_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_POS_IGNORE; bool vel_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_VEL_IGNORE; bool acc_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_ACC_IGNORE; bool yaw_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_IGNORE; bool yaw_rate_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_RATE_IGNORE; // prepare target position Location target_loc = rover.current_loc; if (!pos_ignore) { switch (packet.coordinate_frame) { case MAV_FRAME_BODY_NED: case MAV_FRAME_BODY_OFFSET_NED: { // rotate from body-frame to NE frame const float ne_x = packet.x * rover.ahrs.cos_yaw() - packet.y * rover.ahrs.sin_yaw(); const float ne_y = packet.x * rover.ahrs.sin_yaw() + packet.y * rover.ahrs.cos_yaw(); // add offset to current location location_offset(target_loc, ne_x, ne_y); } break; case MAV_FRAME_LOCAL_OFFSET_NED: // add offset to current location location_offset(target_loc, packet.x, packet.y); break; default: // MAV_FRAME_LOCAL_NED interpret as an offset from home target_loc = rover.ahrs.get_home(); location_offset(target_loc, packet.x, packet.y); break; } } float target_speed = 0.0f; float target_yaw_cd = 0.0f; // consume velocity and convert to target speed and heading if (!vel_ignore) { const float speed_max = rover.control_mode->get_speed_default(); // convert vector length into a speed target_speed = constrain_float(safe_sqrt(sq(packet.vx) + sq(packet.vy)), -speed_max, speed_max); // convert vector direction to target yaw target_yaw_cd = degrees(atan2f(packet.vy, packet.vx)) * 100.0f; // rotate target yaw if provided in body-frame if (packet.coordinate_frame == MAV_FRAME_BODY_NED || packet.coordinate_frame == MAV_FRAME_BODY_OFFSET_NED) { target_yaw_cd = wrap_180_cd(target_yaw_cd + rover.ahrs.yaw_sensor); } } // consume yaw heading if (!yaw_ignore) { target_yaw_cd = ToDeg(packet.yaw) * 100.0f; // rotate target yaw if provided in body-frame if (packet.coordinate_frame == MAV_FRAME_BODY_NED || packet.coordinate_frame == MAV_FRAME_BODY_OFFSET_NED) { target_yaw_cd = wrap_180_cd(target_yaw_cd + rover.ahrs.yaw_sensor); } } // consume yaw rate float target_turn_rate_cds = 0.0f; if (!yaw_rate_ignore) { target_turn_rate_cds = ToDeg(packet.yaw_rate) * 100.0f; } // handling case when both velocity and either yaw or yaw-rate are provided // by default, we consider that the rover will drive forward float speed_dir = 1.0f; if (!vel_ignore && (!yaw_ignore || !yaw_rate_ignore)) { // Note: we are using the x-axis velocity to determine direction even though // the frame may have been provided in MAV_FRAME_LOCAL_OFFSET_NED or MAV_FRAME_LOCAL_NED if (is_negative(packet.vx)) { speed_dir = -1.0f; } } // set guided mode targets if (!pos_ignore && vel_ignore && acc_ignore && yaw_ignore && yaw_rate_ignore) { // consume position target rover.mode_guided.set_desired_location(target_loc); } else if (pos_ignore && !vel_ignore && acc_ignore && yaw_ignore && yaw_rate_ignore) { // consume velocity rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, speed_dir * target_speed); } else if (pos_ignore && !vel_ignore && acc_ignore && yaw_ignore && !yaw_rate_ignore) { // consume velocity and turn rate rover.mode_guided.set_desired_turn_rate_and_speed(target_turn_rate_cds, speed_dir * target_speed); } else if (pos_ignore && !vel_ignore && acc_ignore && !yaw_ignore && yaw_rate_ignore) { // consume velocity rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, speed_dir * target_speed); } else if (pos_ignore && vel_ignore && acc_ignore && !yaw_ignore && yaw_rate_ignore) { // consume just target heading (probably only skid steering vehicles can do this) rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, 0.0f); } else if (pos_ignore && vel_ignore && acc_ignore && yaw_ignore && !yaw_rate_ignore) { // consume just turn rate(probably only skid steering vehicles can do this) rover.mode_guided.set_desired_turn_rate_and_speed(target_turn_rate_cds, 0.0f); } break; } case MAVLINK_MSG_ID_SET_POSITION_TARGET_GLOBAL_INT: // MAV ID: 86 { // decode packet mavlink_set_position_target_global_int_t packet; mavlink_msg_set_position_target_global_int_decode(msg, &packet); // exit if vehicle is not in Guided mode if (rover.control_mode != &rover.mode_guided) { break; } // check for supported coordinate frames if (packet.coordinate_frame != MAV_FRAME_GLOBAL && packet.coordinate_frame != MAV_FRAME_GLOBAL_INT && packet.coordinate_frame != MAV_FRAME_GLOBAL_RELATIVE_ALT && packet.coordinate_frame != MAV_FRAME_GLOBAL_RELATIVE_ALT_INT && packet.coordinate_frame != MAV_FRAME_GLOBAL_TERRAIN_ALT && packet.coordinate_frame != MAV_FRAME_GLOBAL_TERRAIN_ALT_INT) { break; } bool pos_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_POS_IGNORE; bool vel_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_VEL_IGNORE; bool acc_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_ACC_IGNORE; bool yaw_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_IGNORE; bool yaw_rate_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_RATE_IGNORE; // prepare target position Location target_loc = rover.current_loc; if (!pos_ignore) { // sanity check location if (!check_latlng(packet.lat_int, packet.lon_int)) { // result = MAV_RESULT_FAILED; break; } target_loc.lat = packet.lat_int; target_loc.lng = packet.lon_int; } float target_speed = 0.0f; float target_yaw_cd = 0.0f; // consume velocity and convert to target speed and heading if (!vel_ignore) { const float speed_max = rover.control_mode->get_speed_default(); // convert vector length into a speed target_speed = constrain_float(safe_sqrt(sq(packet.vx) + sq(packet.vy)), -speed_max, speed_max); // convert vector direction to target yaw target_yaw_cd = degrees(atan2f(packet.vy, packet.vx)) * 100.0f; // rotate target yaw if provided in body-frame if (packet.coordinate_frame == MAV_FRAME_BODY_NED || packet.coordinate_frame == MAV_FRAME_BODY_OFFSET_NED) { target_yaw_cd = wrap_180_cd(target_yaw_cd + rover.ahrs.yaw_sensor); } } // consume yaw heading if (!yaw_ignore) { target_yaw_cd = ToDeg(packet.yaw) * 100.0f; // rotate target yaw if provided in body-frame if (packet.coordinate_frame == MAV_FRAME_BODY_NED || packet.coordinate_frame == MAV_FRAME_BODY_OFFSET_NED) { target_yaw_cd = wrap_180_cd(target_yaw_cd + rover.ahrs.yaw_sensor); } } // consume yaw rate float target_turn_rate_cds = 0.0f; if (!yaw_rate_ignore) { target_turn_rate_cds = ToDeg(packet.yaw_rate) * 100.0f; } // handling case when both velocity and either yaw or yaw-rate are provided // by default, we consider that the rover will drive forward float speed_dir = 1.0f; if (!vel_ignore && (!yaw_ignore || !yaw_rate_ignore)) { // Note: we are using the x-axis velocity to determine direction even though // the frame is provided in MAV_FRAME_GLOBAL_xxx if (is_negative(packet.vx)) { speed_dir = -1.0f; } } // set guided mode targets if (!pos_ignore && vel_ignore && acc_ignore && yaw_ignore && yaw_rate_ignore) { // consume position target rover.mode_guided.set_desired_location(target_loc); } else if (pos_ignore && !vel_ignore && acc_ignore && yaw_ignore && yaw_rate_ignore) { // consume velocity rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, speed_dir * target_speed); } else if (pos_ignore && !vel_ignore && acc_ignore && yaw_ignore && !yaw_rate_ignore) { // consume velocity and turn rate rover.mode_guided.set_desired_turn_rate_and_speed(target_turn_rate_cds, speed_dir * target_speed); } else if (pos_ignore && !vel_ignore && acc_ignore && !yaw_ignore && yaw_rate_ignore) { // consume velocity rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, speed_dir * target_speed); } else if (pos_ignore && vel_ignore && acc_ignore && !yaw_ignore && yaw_rate_ignore) { // consume just target heading (probably only skid steering vehicles can do this) rover.mode_guided.set_desired_heading_and_speed(target_yaw_cd, 0.0f); } else if (pos_ignore && vel_ignore && acc_ignore && yaw_ignore && !yaw_rate_ignore) { // consume just turn rate(probably only skid steering vehicles can do this) rover.mode_guided.set_desired_turn_rate_and_speed(target_turn_rate_cds, 0.0f); } break; } #if HIL_MODE != HIL_MODE_DISABLED case MAVLINK_MSG_ID_HIL_STATE: { mavlink_hil_state_t packet; mavlink_msg_hil_state_decode(msg, &packet); // sanity check location if (!check_latlng(packet.lat, packet.lon)) { break; } // set gps hil sensor Location loc; loc.lat = packet.lat; loc.lng = packet.lon; loc.alt = packet.alt/10; Vector3f vel(packet.vx, packet.vy, packet.vz); vel *= 0.01f; gps.setHIL(0, AP_GPS::GPS_OK_FIX_3D, packet.time_usec/1000, loc, vel, 10, 0); // rad/sec Vector3f gyros; gyros.x = packet.rollspeed; gyros.y = packet.pitchspeed; gyros.z = packet.yawspeed; // m/s/s Vector3f accels; accels.x = packet.xacc * (GRAVITY_MSS/1000.0f); accels.y = packet.yacc * (GRAVITY_MSS/1000.0f); accels.z = packet.zacc * (GRAVITY_MSS/1000.0f); ins.set_gyro(0, gyros); ins.set_accel(0, accels); compass.setHIL(0, packet.roll, packet.pitch, packet.yaw); compass.setHIL(1, packet.roll, packet.pitch, packet.yaw); break; } #endif // HIL_MODE #if MOUNT == ENABLED // deprecated. Use MAV_CMD_DO_MOUNT_CONFIGURE case MAVLINK_MSG_ID_MOUNT_CONFIGURE: { rover.camera_mount.configure_msg(msg); break; } // deprecated. Use MAV_CMD_DO_MOUNT_CONTROL case MAVLINK_MSG_ID_MOUNT_CONTROL: { rover.camera_mount.control_msg(msg); break; } #endif // MOUNT == ENABLED case MAVLINK_MSG_ID_RADIO: case MAVLINK_MSG_ID_RADIO_STATUS: { handle_radio_status(msg, rover.DataFlash, rover.should_log(MASK_LOG_PM)); break; } // send or receive fence points with GCS case MAVLINK_MSG_ID_FENCE_POINT: // MAV ID: 160 case MAVLINK_MSG_ID_FENCE_FETCH_POINT: rover.g2.fence.handle_msg(*this, msg); break; case MAVLINK_MSG_ID_DISTANCE_SENSOR: rover.rangefinder.handle_msg(msg); rover.g2.proximity.handle_msg(msg); break; default: handle_common_message(msg); break; } // end switch } // end handle mavlink