void taskUpdateDisplay(void) { if (feature(FEATURE_DISPLAY)) { updateDisplay(); } }
void processRx(void) { static bool armedBeeperOn = false; calculateRxChannelsAndUpdateFailsafe(currentTime); // in 3D mode, we need to be able to disarm by switch at any time if (feature(FEATURE_3D)) { if (!rcModeIsActive(BOXARM)) mwDisarm(); } updateRSSI(currentTime); if (feature(FEATURE_FAILSAFE)) { if (currentTime > FAILSAFE_POWER_ON_DELAY_US && !failsafeIsMonitoring()) { failsafeStartMonitoring(); } failsafeUpdateState(); } throttleStatus_e throttleStatus = calculateThrottleStatus(rxConfig(), rcControlsConfig()->deadband3d_throttle); rollPitchStatus_e rollPitchStatus = calculateRollPitchCenterStatus(rxConfig()); /* In airmode Iterm should be prevented to grow when Low thottle and Roll + Pitch Centered. This is needed to prevent Iterm winding on the ground, but keep full stabilisation on 0 throttle while in air Low Throttle + roll and Pitch centered is assuming the copter is on the ground. Done to prevent complex air/ground detections */ if (throttleStatus == THROTTLE_LOW) { if (rcModeIsActive(BOXAIRMODE) && !failsafeIsActive() && ARMING_FLAG(ARMED)) { if (rollPitchStatus == CENTERED) { ENABLE_STATE(ANTI_WINDUP); } else { DISABLE_STATE(ANTI_WINDUP); } } else { #ifndef SKIP_PID_MW23 pidResetITermAngle(); #endif pidResetITerm(); } } else { DISABLE_STATE(ANTI_WINDUP); } // When armed and motors aren't spinning, do beeps and then disarm // board after delay so users without buzzer won't lose fingers. // mixTable constrains motor commands, so checking throttleStatus is enough if (ARMING_FLAG(ARMED) && feature(FEATURE_MOTOR_STOP) && !STATE(FIXED_WING) ) { if (isUsingSticksForArming()) { if (throttleStatus == THROTTLE_LOW) { if (armingConfig()->auto_disarm_delay != 0 && (int32_t)(disarmAt - millis()) < 0 ) { // auto-disarm configured and delay is over mwDisarm(); armedBeeperOn = false; } else { // still armed; do warning beeps while armed beeper(BEEPER_ARMED); armedBeeperOn = true; } } else { // throttle is not low if (armingConfig()->auto_disarm_delay != 0) { // extend disarm time disarmAt = millis() + armingConfig()->auto_disarm_delay * 1000; } if (armedBeeperOn) { beeperSilence(); armedBeeperOn = false; } } } else { // arming is via AUX switch; beep while throttle low if (throttleStatus == THROTTLE_LOW) { beeper(BEEPER_ARMED); armedBeeperOn = true; } else if (armedBeeperOn) { beeperSilence(); armedBeeperOn = false; } } } processRcStickPositions(rxConfig(), throttleStatus, armingConfig()->retarded_arm, armingConfig()->disarm_kill_switch); if (feature(FEATURE_INFLIGHT_ACC_CAL)) { updateInflightCalibrationState(); } rcModeUpdateActivated(modeActivationProfile()->modeActivationConditions); if (!cliMode) { updateAdjustmentStates(adjustmentProfile()->adjustmentRanges); processRcAdjustments(currentControlRateProfile, rxConfig()); } bool canUseHorizonMode = true; if ((rcModeIsActive(BOXANGLE) || (feature(FEATURE_FAILSAFE) && failsafeIsActive())) && (sensors(SENSOR_ACC))) { // bumpless transfer to Level mode canUseHorizonMode = false; if (!FLIGHT_MODE(ANGLE_MODE)) { #ifndef SKIP_PID_MW23 pidResetITermAngle(); #endif ENABLE_FLIGHT_MODE(ANGLE_MODE); } } else { DISABLE_FLIGHT_MODE(ANGLE_MODE); // failsafe support } if (rcModeIsActive(BOXHORIZON) && canUseHorizonMode) { DISABLE_FLIGHT_MODE(ANGLE_MODE); if (!FLIGHT_MODE(HORIZON_MODE)) { #ifndef SKIP_PID_MW23 pidResetITermAngle(); #endif ENABLE_FLIGHT_MODE(HORIZON_MODE); } } else { DISABLE_FLIGHT_MODE(HORIZON_MODE); } if (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE)) { LED1_ON; } else { LED1_OFF; } #ifdef MAG if (sensors(SENSOR_ACC) || sensors(SENSOR_MAG)) { if (rcModeIsActive(BOXMAG)) { if (!FLIGHT_MODE(MAG_MODE)) { ENABLE_FLIGHT_MODE(MAG_MODE); magHold = DECIDEGREES_TO_DEGREES(attitude.values.yaw); } } else { DISABLE_FLIGHT_MODE(MAG_MODE); } if (rcModeIsActive(BOXHEADFREE)) { if (!FLIGHT_MODE(HEADFREE_MODE)) { ENABLE_FLIGHT_MODE(HEADFREE_MODE); } } else { DISABLE_FLIGHT_MODE(HEADFREE_MODE); } if (rcModeIsActive(BOXHEADADJ)) { headFreeModeHold = DECIDEGREES_TO_DEGREES(attitude.values.yaw); // acquire new heading } } #endif #ifdef GPS if (sensors(SENSOR_GPS)) { updateGpsWaypointsAndMode(); } #endif if (rcModeIsActive(BOXPASSTHRU)) { ENABLE_FLIGHT_MODE(PASSTHRU_MODE); } else { DISABLE_FLIGHT_MODE(PASSTHRU_MODE); } if (mixerConfig()->mixerMode == MIXER_FLYING_WING || mixerConfig()->mixerMode == MIXER_AIRPLANE) { DISABLE_FLIGHT_MODE(HEADFREE_MODE); } #ifdef TELEMETRY if (feature(FEATURE_TELEMETRY)) { if ((!telemetryConfig()->telemetry_switch && ARMING_FLAG(ARMED)) || (telemetryConfig()->telemetry_switch && rcModeIsActive(BOXTELEMETRY))) { releaseSharedTelemetryPorts(); } else { // the telemetry state must be checked immediately so that shared serial ports are released. telemetryCheckState(); mspSerialAllocatePorts(); } } #endif }
void taskMainPidLoop(void) { cycleTime = getTaskDeltaTime(TASK_SELF); dT = (float)cycleTime * 0.000001f; // Calculate average cycle time and average jitter filteredCycleTime = filterApplyPt1(cycleTime, &filteredCycleTimeState, 1, dT); debug[0] = cycleTime; debug[1] = cycleTime - filteredCycleTime; imuUpdateGyroAndAttitude(); annexCode(); if (rxConfig()->rcSmoothing) { filterRc(); } #if defined(BARO) || defined(SONAR) haveProcessedAnnexCodeOnce = true; #endif #ifdef MAG if (sensors(SENSOR_MAG)) { updateMagHold(); } #endif #ifdef GTUNE updateGtuneState(); #endif #if defined(BARO) || defined(SONAR) if (sensors(SENSOR_BARO) || sensors(SENSOR_SONAR)) { if (FLIGHT_MODE(BARO_MODE) || FLIGHT_MODE(SONAR_MODE)) { applyAltHold(); } } #endif // If we're armed, at minimum throttle, and we do arming via the // sticks, do not process yaw input from the rx. We do this so the // motors do not spin up while we are trying to arm or disarm. // Allow yaw control for tricopters if the user wants the servo to move even when unarmed. if (isUsingSticksForArming() && rcData[THROTTLE] <= rxConfig()->mincheck #ifndef USE_QUAD_MIXER_ONLY #ifdef USE_SERVOS && !((mixerConfig()->mixerMode == MIXER_TRI || mixerConfig()->mixerMode == MIXER_CUSTOM_TRI) && mixerConfig()->tri_unarmed_servo) #endif && mixerConfig()->mixerMode != MIXER_AIRPLANE && mixerConfig()->mixerMode != MIXER_FLYING_WING #endif ) { rcCommand[YAW] = 0; } if (throttleCorrectionConfig()->throttle_correction_value && (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE))) { rcCommand[THROTTLE] += calculateThrottleAngleCorrection(throttleCorrectionConfig()->throttle_correction_value); } #ifdef GPS if (sensors(SENSOR_GPS)) { if ((FLIGHT_MODE(GPS_HOME_MODE) || FLIGHT_MODE(GPS_HOLD_MODE)) && STATE(GPS_FIX_HOME)) { updateGpsStateForHomeAndHoldMode(); } } #endif // PID - note this is function pointer set by setPIDController() pid_controller( pidProfile(), currentControlRateProfile, imuConfig()->max_angle_inclination, &accelerometerConfig()->accelerometerTrims, rxConfig() ); mixTable(); #ifdef USE_SERVOS filterServos(); writeServos(); #endif if (motorControlEnable) { writeMotors(); } #ifdef USE_SDCARD afatfs_poll(); #endif #ifdef BLACKBOX if (!cliMode && feature(FEATURE_BLACKBOX)) { handleBlackbox(); } #endif }
Configuration ConfigFile::getConfiguration() { Configuration configuration; char **bind; int i; if (!m_loaded) return DummyConfiguration; // Service section LOAD_REQUIRED_STRING(configuration.protocol, "service", "protocol"); std::transform(configuration.protocol.begin(), configuration.protocol.end(), configuration.protocol.begin(), tolower); m_protocol = configuration.protocol; LOAD_REQUIRED_STRING(configuration.jid, "service", "jid"); m_jid = configuration.jid; LOAD_REQUIRED_STRING(configuration.discoName, "service", "name"); LOAD_REQUIRED_STRING(configuration.server, "service", "server"); LOAD_REQUIRED_STRING(configuration.password, "service", "password"); LOAD_REQUIRED_STRING(configuration.filetransferCache, "service", "filetransfer_cache"); LOAD_REQUIRED_STRING_DEFAULT(configuration.config_interface, "service", "config_interface", "/var/run/spectrum/" + configuration.jid + ".sock"); if (!loadInteger(configuration.port, "service", "port")) return DummyConfiguration; loadString(configuration.filetransferWeb, "service", "filetransfer_web", ""); loadString(configuration.pid_f, "service", "pid_file", "/var/run/spectrum/" + configuration.jid); loadString(configuration.language, "service", "language", "en"); loadString(configuration.encoding, "service", "encoding", ""); loadString(configuration.eventloop, "service", "eventloop", "glib"); loadBoolean(configuration.jid_escaping, "service", "jid_escaping", true); loadBoolean(configuration.onlyForVIP, "service", "only_for_vip", false); loadBoolean(configuration.VIPEnabled, "service", "vip_mode", false); loadBoolean(configuration.useProxy, "service", "use_proxy", false); loadBoolean(configuration.require_tls, "service", "require_tls", true); loadStringList(configuration.allowedServers, "service", "allowed_servers"); loadStringList(configuration.admins, "service", "admins"); loadHostPort(configuration.filetransfer_proxy_ip, configuration.filetransfer_proxy_port, "service", "filetransfer_bind_address", "", 0); loadHostPort(configuration.filetransfer_proxy_streamhost_ip, configuration.filetransfer_proxy_streamhost_port, "service", "filetransfer_public_address", configuration.filetransfer_proxy_ip, configuration.filetransfer_proxy_port); if (!loadFeatures(configuration.transportFeatures, "features")) { configuration.transportFeatures = TRANSPORT_FEATURE_ALL; // TODO: transport_features and vip_features are depracted. remove it for 0.4 if(g_key_file_has_key(keyfile,"service","transport_features",NULL)) { bind = g_key_file_get_string_list (keyfile,"service","transport_features",NULL, NULL); configuration.transportFeatures = 0; for (i = 0; bind[i]; i++){ std::string feature(bind[i]); if (feature == "avatars") configuration.transportFeatures = configuration.transportFeatures | TRANSPORT_FEATURE_AVATARS; else if (feature == "chatstate") configuration.transportFeatures = configuration.transportFeatures | TRANSPORT_FEATURE_TYPING_NOTIFY; else if (feature == "filetransfer") configuration.transportFeatures = configuration.transportFeatures | TRANSPORT_FEATURE_FILETRANSFER; } g_strfreev (bind); } else configuration.transportFeatures = TRANSPORT_FEATURE_AVATARS | TRANSPORT_FEATURE_FILETRANSFER | TRANSPORT_FEATURE_TYPING_NOTIFY; } if (!loadFeatures(configuration.VIPFeatures, "vip-features")) { configuration.VIPFeatures = TRANSPORT_FEATURE_ALL; if(g_key_file_has_key(keyfile,"service","vip_features",NULL)) { bind = g_key_file_get_string_list (keyfile,"service","vip_features",NULL, NULL); configuration.VIPFeatures = 0; for (i = 0; bind[i]; i++){ std::string feature(bind[i]); if (feature == "avatars") configuration.VIPFeatures |= TRANSPORT_FEATURE_AVATARS; else if (feature == "chatstate") configuration.VIPFeatures |= TRANSPORT_FEATURE_TYPING_NOTIFY; else if (feature == "filetransfer") configuration.VIPFeatures |= TRANSPORT_FEATURE_FILETRANSFER; } g_strfreev (bind); } else configuration.VIPFeatures = TRANSPORT_FEATURE_AVATARS | TRANSPORT_FEATURE_FILETRANSFER | TRANSPORT_FEATURE_TYPING_NOTIFY; } // Database section LOAD_REQUIRED_STRING(configuration.sqlType, "database", "type"); LOAD_REQUIRED_STRING(configuration.sqlDb, "database", "database"); LOAD_REQUIRED_STRING_DEFAULT(configuration.sqlHost, "database", "host", configuration.sqlType == "sqlite" ? "optional" : ""); LOAD_REQUIRED_STRING_DEFAULT(configuration.sqlPassword, "database", "password", configuration.sqlType == "sqlite" ? "optional" : ""); LOAD_REQUIRED_STRING_DEFAULT(configuration.sqlUser, "database", "user", configuration.sqlType == "sqlite" ? "optional" : ""); LOAD_REQUIRED_STRING_DEFAULT(configuration.sqlPrefix, "database", "prefix", configuration.sqlType == "sqlite" ? "" : "required"); loadString(configuration.sqlVIP, "database", "vip_statement", ""); LOAD_REQUIRED_STRING(configuration.userDir, "purple", "userdir"); // Logging section loadString(configuration.logfile, "logging", "log_file", ""); if (g_key_file_has_key(keyfile, "logging", "log_areas", NULL)) { bind = g_key_file_get_string_list(keyfile, "logging", "log_areas", NULL, NULL); configuration.logAreas = 0; for (i = 0; bind[i]; i++) { std::string feature(bind[i]); if (feature == "xml") { configuration.logAreas = configuration.logAreas | LOG_AREA_XML; } else if (feature == "purple") configuration.logAreas = configuration.logAreas | LOG_AREA_PURPLE; } g_strfreev (bind); } else configuration.logAreas = LOG_AREA_XML | LOG_AREA_PURPLE; // Registration section loadBoolean(configuration.enable_public_registration, "registration", "enable_public_registration", true); loadString(configuration.username_mask, "registration", "username_mask", ""); loadString(configuration.reg_instructions, "registration", "instructions", ""); loadString(configuration.reg_username_field, "registration", "username_label", ""); loadString(configuration.reg_allowed_usernames, "registration", "allowed_usernames", ""); if (configuration.sqlType == "sqlite") create_dir(configuration.sqlDb, 0750); create_dir(configuration.filetransferCache, 0750); create_dir(configuration.config_interface, 0750); create_dir(configuration.pid_f, 0750); create_dir(configuration.userDir, 0750); create_dir(configuration.logfile, 0750); return configuration; }