mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-09 22:49:53 +08:00
Merge pull request #1062 from paparazzi/opticflow
Add cv_opticflow.xml module. Used to for hover stabilization on an ARDrone2. Also adds AP_MODE_MODULE to make it easier to add extra "external" control loops.
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
<!DOCTYPE airframe SYSTEM "airframe.dtd">
|
||||
|
||||
<airframe name="ardrone2_raw">
|
||||
|
||||
<firmware name="rotorcraft">
|
||||
<target name="ap" board="ardrone2_raw">
|
||||
<subsystem name="telemetry" type="transparent_udp"/>
|
||||
<subsystem name="radio_control" type="datalink"/>
|
||||
</target>
|
||||
|
||||
<!--target name="nps" board="pc">
|
||||
<subsystem name="fdm" type="jsbsim"/>
|
||||
<subsystem name="radio_control" type="ppm"/>
|
||||
</target-->
|
||||
|
||||
<define name="USE_SONAR" value="TRUE"/>
|
||||
|
||||
<!-- Subsystem section -->
|
||||
<subsystem name="motor_mixing"/>
|
||||
<subsystem name="actuators" type="ardrone2"/>
|
||||
<subsystem name="imu" type="ardrone2"/>
|
||||
<subsystem name="gps" type="ublox"/>
|
||||
<subsystem name="stabilization" type="int_quat"/>
|
||||
<subsystem name="ahrs" type="int_cmpl_quat"/>
|
||||
<subsystem name="ins" type="extended"/>
|
||||
</firmware>
|
||||
|
||||
<modules main_freq="512">
|
||||
<load name="gps_ubx_ucenter.xml"/>
|
||||
<load name="send_imu_mag_current.xml"/>
|
||||
<load name="file_logger.xml"/>
|
||||
<load name="cv_opticflow.xml"/>
|
||||
</modules>
|
||||
|
||||
<commands>
|
||||
<axis name="PITCH" failsafe_value="0"/>
|
||||
<axis name="ROLL" failsafe_value="0"/>
|
||||
<axis name="YAW" failsafe_value="0"/>
|
||||
<axis name="THRUST" failsafe_value="3000"/>
|
||||
</commands>
|
||||
|
||||
<servos driver="Default">
|
||||
<servo name="TOP_LEFT" no="0" min="0" neutral="1" max="500"/>
|
||||
<servo name="TOP_RIGHT" no="1" min="0" neutral="1" max="500"/>
|
||||
<servo name="BOTTOM_RIGHT" no="2" min="0" neutral="1" max="500"/>
|
||||
<servo name="BOTTOM_LEFT" no="3" min="0" neutral="1" max="500"/>
|
||||
</servos>
|
||||
|
||||
<section name="MIXING" prefix="MOTOR_MIXING_">
|
||||
<define name="TRIM_ROLL" value="0"/>
|
||||
<define name="TRIM_PITCH" value="0"/>
|
||||
<define name="TRIM_YAW" value="0"/>
|
||||
<define name="NB_MOTOR" value="4"/>
|
||||
<define name="SCALE" value="255"/>
|
||||
|
||||
<!-- Time cross layout (X), with order NW (CW), NE (CCW), SE (CW), SW (CCW) -->
|
||||
<define name="ROLL_COEF" value="{ 256, -256, -256, 256 }"/>
|
||||
<define name="PITCH_COEF" value="{ 256, 256, -256, -256 }"/>
|
||||
<define name="YAW_COEF" value="{ -256, 256, -256, 256 }"/>
|
||||
<define name="THRUST_COEF" value="{ 256, 256, 256, 256 }"/>
|
||||
</section>
|
||||
|
||||
<command_laws>
|
||||
<call fun="motor_mixing_run(autopilot_motors_on,FALSE,values)"/>
|
||||
<set servo="TOP_LEFT" value="motor_mixing.commands[0]"/>
|
||||
<set servo="TOP_RIGHT" value="motor_mixing.commands[1]"/>
|
||||
<set servo="BOTTOM_RIGHT" value="motor_mixing.commands[2]"/>
|
||||
<set servo="BOTTOM_LEFT" value="motor_mixing.commands[3]"/>
|
||||
</command_laws>
|
||||
|
||||
<section name="VISION" prefix="VISION_">
|
||||
<define name="HOVER" value="FALSE"/>
|
||||
<define name="PHI_PGAIN" value="500"/>
|
||||
<define name="PHI_IGAIN" value="10"/>
|
||||
<define name="THETA_PGAIN" value="500"/>
|
||||
<define name="THETA_IGAIN" value="10"/>
|
||||
<define name="DESIRED_VX" value="0"/>
|
||||
<define name="DESIRED_VY" value="0"/>
|
||||
</section>
|
||||
|
||||
<section name="IMU" prefix="IMU_">
|
||||
<!-- Accelero -->
|
||||
<define name="ACCEL_X_NEUTRAL" value="2048"/>
|
||||
<define name="ACCEL_Y_NEUTRAL" value="2048"/>
|
||||
<define name="ACCEL_Z_NEUTRAL" value="2048"/>
|
||||
|
||||
<!-- Magneto calibration -->
|
||||
<define name="MAG_X_NEUTRAL" value="0"/>
|
||||
<define name="MAG_Y_NEUTRAL" value="0"/>
|
||||
<define name="MAG_Z_NEUTRAL" value="-180"/>
|
||||
<define name="MAG_X_SENS" value="16." integer="16"/>
|
||||
<define name="MAG_Y_SENS" value="16." integer="16"/>
|
||||
<define name="MAG_Z_SENS" value="16." integer="16"/>
|
||||
|
||||
<!-- Magneto current calibration -->
|
||||
<define name="MAG_X_CURRENT_COEF" value="0.0"/>
|
||||
<define name="MAG_Y_CURRENT_COEF" value="0.0"/>
|
||||
<define name="MAG_Z_CURRENT_COEF" value="0.0"/>
|
||||
|
||||
<define name="BODY_TO_IMU_PHI" value="0." unit="deg"/>
|
||||
<define name="BODY_TO_IMU_THETA" value="0." unit="deg"/>
|
||||
<define name="BODY_TO_IMU_PSI" value="0." unit="deg"/>
|
||||
</section>
|
||||
|
||||
<!-- local magnetic field -->
|
||||
<!-- http://wiki.paparazziuav.org/wiki/Subsystem/ahrs#Local_Magnetic_Field -->
|
||||
<section name="AHRS" prefix="AHRS_">
|
||||
<!-- Toulouse -->
|
||||
<define name="H_X" value="0.513081"/>
|
||||
<define name="H_Y" value="-0.00242783"/>
|
||||
<define name="H_Z" value="0.858336"/>
|
||||
<!-- Delft -->
|
||||
<!--define name="H_X" value="0.3892503"/>
|
||||
<define name="H_Y" value="0.0017972"/>
|
||||
<define name="H_Z" value="0.9211303"/ -->
|
||||
</section>
|
||||
|
||||
<section name="INS" prefix="INS_">
|
||||
<define name="SONAR_MAX_RANGE" value="2.2"/>
|
||||
<define name="SONAR_UPDATE_ON_AGL" value="TRUE"/>
|
||||
</section>
|
||||
|
||||
<section name="STABILIZATION_RATE" prefix="STABILIZATION_RATE_">
|
||||
<!-- setpoints -->
|
||||
<define name="SP_MAX_P" value="10000"/>
|
||||
<define name="SP_MAX_Q" value="10000"/>
|
||||
<define name="SP_MAX_R" value="10000"/>
|
||||
<define name="DEADBAND_P" value="20"/>
|
||||
<define name="DEADBAND_Q" value="20"/>
|
||||
<define name="DEADBAND_R" value="200"/>
|
||||
<define name="REF_TAU" value="4"/>
|
||||
|
||||
<!-- feedback -->
|
||||
<define name="GAIN_P" value="400"/>
|
||||
<define name="GAIN_Q" value="400"/>
|
||||
<define name="GAIN_R" value="350"/>
|
||||
|
||||
<define name="IGAIN_P" value="75"/>
|
||||
<define name="IGAIN_Q" value="75"/>
|
||||
<define name="IGAIN_R" value="50"/>
|
||||
|
||||
<!-- feedforward -->
|
||||
<define name="DDGAIN_P" value="300"/>
|
||||
<define name="DDGAIN_Q" value="300"/>
|
||||
<define name="DDGAIN_R" value="300"/>
|
||||
</section>
|
||||
|
||||
<section name="STABILIZATION_ATTITUDE" prefix="STABILIZATION_ATTITUDE_">
|
||||
<!-- setpoints -->
|
||||
<define name="SP_MAX_PHI" value="45" unit="deg"/>
|
||||
<define name="SP_MAX_THETA" value="45" unit="deg"/>
|
||||
<define name="SP_MAX_R" value="600" unit="deg/s"/>
|
||||
<define name="DEADBAND_A" value="0"/>
|
||||
<define name="DEADBAND_E" value="0"/>
|
||||
<define name="DEADBAND_R" value="250"/>
|
||||
|
||||
<!-- reference -->
|
||||
<define name="REF_OMEGA_P" value="450" unit="deg/s"/>
|
||||
<define name="REF_ZETA_P" value="0.9"/>
|
||||
<define name="REF_MAX_P" value="600." unit="deg/s"/>
|
||||
<define name="REF_MAX_PDOT" value="RadOfDeg(8000.)"/>
|
||||
|
||||
<define name="REF_OMEGA_Q" value="450" unit="deg/s"/>
|
||||
<define name="REF_ZETA_Q" value="0.9"/>
|
||||
<define name="REF_MAX_Q" value="600." unit="deg/s"/>
|
||||
<define name="REF_MAX_QDOT" value="RadOfDeg(8000.)"/>
|
||||
|
||||
<define name="REF_OMEGA_R" value="200" unit="deg/s"/>
|
||||
<define name="REF_ZETA_R" value="0.9"/>
|
||||
<define name="REF_MAX_R" value="300." unit="deg/s"/>
|
||||
<define name="REF_MAX_RDOT" value="RadOfDeg(4000.)"/>
|
||||
|
||||
<!-- feedback -->
|
||||
<define name="PHI_PGAIN" value="592"/>
|
||||
<define name="PHI_DGAIN" value="303"/>
|
||||
<define name="PHI_IGAIN" value="0"/>
|
||||
|
||||
<define name="THETA_PGAIN" value="606"/>
|
||||
<define name="THETA_DGAIN" value="303"/>
|
||||
<define name="THETA_IGAIN" value="0"/>
|
||||
|
||||
<define name="PSI_PGAIN" value="529"/>
|
||||
<define name="PSI_DGAIN" value="353"/>
|
||||
<define name="PSI_IGAIN" value="0"/>
|
||||
|
||||
<!-- feedforward -->
|
||||
<define name="PHI_DDGAIN" value="0"/>
|
||||
<define name="THETA_DDGAIN" value="0"/>
|
||||
<define name="PSI_DDGAIN" value="52"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_V" prefix="GUIDANCE_V_">
|
||||
<define name="HOVER_KP" value="283"/>
|
||||
<define name="HOVER_KD" value="82"/>
|
||||
<define name="HOVER_KI" value="13"/>
|
||||
<define name="NOMINAL_HOVER_THROTTLE" value="0.655"/>
|
||||
<define name="ADAPT_THROTTLE_ENABLED" value="FALSE"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_H" prefix="GUIDANCE_H_">
|
||||
<!-- Good weather -->
|
||||
<define name="MAX_BANK" value="20" unit="deg"/>
|
||||
<!-- Bad weather -->
|
||||
<!-- define name="MAX_BANK" value="32" unit="deg"/ -->
|
||||
<define name="PGAIN" value="79"/>
|
||||
<define name="DGAIN" value="100"/>
|
||||
<define name="IGAIN" value="30"/>
|
||||
</section>
|
||||
|
||||
<section name="SIMULATOR" prefix="NPS_">
|
||||
<define name="ACTUATOR_NAMES" value="{"nw_motor", "ne_motor", "se_motor", "sw_motor"}"/>
|
||||
<define name="JSBSIM_MODEL" value=""simple_ardrone2""/>
|
||||
<define name="SENSORS_PARAMS" value=""nps_sensors_params_ardrone2.h""/>
|
||||
</section>
|
||||
|
||||
<section name="AUTOPILOT">
|
||||
<define name="MODE_STARTUP" value="AP_MODE_NAV"/>
|
||||
<define name="MODE_MANUAL" value="AP_MODE_ATTITUDE_DIRECT"/>
|
||||
<define name="MODE_AUTO1" value="AP_MODE_MODULE"/>
|
||||
<define name="MODE_AUTO2" value="AP_MODE_NAV"/>
|
||||
</section>
|
||||
|
||||
<section name="BAT">
|
||||
<define name="MILLIAMP_AT_FULL_THROTTLE" value="8700"/>
|
||||
<define name="CATASTROPHIC_BAT_LEVEL" value="9.3" unit="V"/>
|
||||
<define name="CRITIC_BAT_LEVEL" value="9.6" unit="V"/>
|
||||
<define name="LOW_BAT_LEVEL" value="9.7" unit="V"/>
|
||||
<define name="MAX_BAT_LEVEL" value="12.4" unit="V"/>
|
||||
</section>
|
||||
</airframe>
|
||||
@@ -318,6 +318,17 @@
|
||||
settings_modules="modules/meteo_france_DAQ.xml"
|
||||
gui_color="blue"
|
||||
/>
|
||||
<aircraft
|
||||
name="ardrone2_opticflow"
|
||||
ac_id="2"
|
||||
airframe="airframes/ardrone2_opticflow_hover.xml"
|
||||
radio="radios/cockpitSX.xml"
|
||||
telemetry="telemetry/default_ardrone.xml"
|
||||
flight_plan="flight_plans/rotorcraft_basic.xml"
|
||||
settings="settings/rotorcraft_basic.xml settings/control/rotorcraft_guidance.xml settings/control/stabilization_rate.xml settings/control/stabilization_att_int.xml"
|
||||
settings_modules="modules/gps_ubx_ucenter.xml modules/cv_opticflow.xml"
|
||||
gui_color="blue"
|
||||
/>
|
||||
<aircraft
|
||||
name="ardrone2_raw"
|
||||
ac_id="201"
|
||||
|
||||
+25
-3
@@ -1972,8 +1972,30 @@
|
||||
<field name="t" type="uint32"/>
|
||||
</message>
|
||||
|
||||
<!--228 is free -->
|
||||
<!--229 is free -->
|
||||
<message name="OF_HOVER" id="228">
|
||||
<field name="FPS" type="float"/>
|
||||
<field name="dx" type="float"/>
|
||||
<field name="dy" type="float"/>
|
||||
<field name="dx_trans" type="float"/>
|
||||
<field name="dy_trans" type="float"/>
|
||||
<field name="diff_roll" type="float"/>
|
||||
<field name="diff_pitch" type="float"/>
|
||||
<field name="velx" type="float"/>
|
||||
<field name="vely" type="float"/>
|
||||
<field name="velx_Ned" type="float"/>
|
||||
<field name="vely_Ned" type="float"/>
|
||||
<field name="z_sonar" type="float"/>
|
||||
<field name="count" type="int32"/>
|
||||
</message>
|
||||
|
||||
<message name="VISION_STABILIZATION" id="229">
|
||||
<field name="velx" type="float"/>
|
||||
<field name="vely" type="float"/>
|
||||
<field name="velx_i" type="float"/>
|
||||
<field name="vely_i" type="float"/>
|
||||
<field name="cmd_phi" type="int32"/>
|
||||
<field name="cmd_theta" type="int32"/>
|
||||
</message>
|
||||
|
||||
<message name="AHRS_ARDRONE2" id="230">
|
||||
<field name="state" type="uint32" />
|
||||
@@ -1997,7 +2019,7 @@
|
||||
<field name="rc_status" type="uint8" values="OK|LOST|REALLY_LOST"/>
|
||||
<field name="frame_rate" type="uint8" unit="Hz"/>
|
||||
<field name="gps_status" type="uint8" values="NO_FIX|NA|NA|3Dfix"/>
|
||||
<field name="ap_mode" type="uint8" values="KILL|FAILSAFE|HOME|RATE_DIRECT|ATTITUDE_DIRECT|RATE_RC_CLIMB|ATTITUDE_RC_CLIMB|ATTITUDE_CLIMB|RATE_Z_HOLD|ATTITUDE_Z_HOLD|HOVER_DIRECT|HOVER_CLIMB|HOVER_Z_HOLD|NAV|RC_DIRECT|CARE_FREE|FORWARD"/>
|
||||
<field name="ap_mode" type="uint8" values="KILL|FAILSAFE|HOME|RATE_DIRECT|ATTITUDE_DIRECT|RATE_RC_CLIMB|ATTITUDE_RC_CLIMB|ATTITUDE_CLIMB|RATE_Z_HOLD|ATTITUDE_Z_HOLD|HOVER_DIRECT|HOVER_CLIMB|HOVER_Z_HOLD|NAV|RC_DIRECT|CARE_FREE|FORWARD|MODULE"/>
|
||||
<field name="ap_in_flight" type="uint8" values="ON_GROUND|IN_FLIGHT"/>
|
||||
<field name="ap_motors_on" type="uint8" values="MOTORS_OFF|MOTORS_ON"/>
|
||||
<field name="ap_h_mode" type="uint8" values="KILL|RATE|ATTITUDE|HOVER|NAV|CF"/>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="ctrl_module_demo" dir="ctrl">
|
||||
<doc>
|
||||
<description>
|
||||
Demo Control Module
|
||||
|
||||
Rate-controller as module sample
|
||||
</description>
|
||||
</doc>
|
||||
<settings>
|
||||
<dl_settings>
|
||||
<dl_settings NAME="CtrlModDemo">
|
||||
<dl_setting var="ctrl_module_demo_pr_ff_gain" min="0" step="0.01" max="1" module="ctrl/ctrl_module_demo" shortname="pr_ff"/>
|
||||
<dl_setting var="ctrl_module_demo_pr_d_gain" min="0" step="0.01" max="1" module="ctrl/ctrl_module_demo" shortname="pr_d"/>
|
||||
<dl_setting var="ctrl_module_demo_y_ff_gain" min="0" step="0.01" max="1" module="ctrl/ctrl_module_demo" shortname="y_ff"/>
|
||||
<dl_setting var="ctrl_module_demo_y_d_gain" min="0" step="0.01" max="1" module="ctrl/ctrl_module_demo" shortname="y_d"/>
|
||||
</dl_settings> </dl_settings>
|
||||
</settings>
|
||||
|
||||
<header>
|
||||
<file name="ctrl_module_demo.h"/>
|
||||
</header>
|
||||
|
||||
<makefile>
|
||||
<file name="ctrl_module_demo.c"/>
|
||||
</makefile>
|
||||
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="cv_opticflow" dir="computer_vision">
|
||||
<doc>
|
||||
<description>
|
||||
Compute Optic Flow from Ardrone2 Bottom Camera
|
||||
|
||||
Computes Pitch- and rollrate corrected optic flow from downward looking
|
||||
ARDrone2 camera looking at a textured floor.
|
||||
|
||||
- Sonar is required.
|
||||
- Controller can hold position
|
||||
</description>
|
||||
|
||||
<section name="VISION" prefix="VISION_">
|
||||
<define name="HOVER" value="FALSE" description="TRUE/FALSE active or not"/>
|
||||
<define name="PHI_PGAIN" value="500" description="optic flow pgain"/>
|
||||
<define name="PHI_IGAIN" value="10" description="optic flow igain"/>
|
||||
<define name="THETA_PGAIN" value="500" description="optic flow pgain"/>
|
||||
<define name="THETA_IGAIN" value="10" description="optic flow igain"/>
|
||||
<define name="DESIRED_VX" value="0" description="feedforward optic flow vx"/>
|
||||
<define name="DESIRED_VY" value="0" description="feedforward optic flow vy"/>
|
||||
</section>
|
||||
<define name="DOWNLINK_VIDEO" value="FALSE" description="Also stream video: warning: this makes the optic flow slow: DEBUGGING only" />
|
||||
<define name="OPTICFLOW_AGL_ID" value="ABI_SENDER_ID" description="ABI sender id for AGL message (sonar measurement) (default: ABI_BROADCAST)"/>
|
||||
</doc>
|
||||
<settings>
|
||||
<dl_settings>
|
||||
<dl_settings NAME="Vision Loop">
|
||||
<dl_setting var="activate_opticflow_hover" min="0" step="1" max="1" module="computer_vision/opticflow/hover_stabilization" shortname="hover" param="VISION_HOVER" values="FALSE|TRUE"/>
|
||||
<dl_setting var="vision_phi_pgain" min="0" step="1" max="10000" shortname="kp_v_phi" param="VISION_PHI_PGAIN"/>
|
||||
<dl_setting var="vision_phi_igain" min="0" step="1" max="1000" shortname="ki_v_phi" param="VISION_PHI_IGAIN"/>
|
||||
<dl_setting var="vision_theta_pgain" min="0" step="1" max="10000" shortname="kp_v_theta" param="VISION_THETA_PGAIN"/>
|
||||
<dl_setting var="vision_theta_igain" min="0" step="1" max="1000" shortname="ki_v_theta" param="VISION_THETA_IGAIN"/>
|
||||
<dl_setting var="vision_desired_vx" min="-5" step="0.01" max="5" shortname="desired_vx" param="VISION_DESIRED_VX"/>
|
||||
<dl_setting var="vision_desired_vy" min="-5" step="0.01" max="5" shortname="desired_vy" param="VISION_DESIRED_VY"/>
|
||||
</dl_settings> </dl_settings>
|
||||
</settings>
|
||||
|
||||
<header>
|
||||
<file name="opticflow_module.h"/>
|
||||
</header>
|
||||
|
||||
<init fun="opticflow_module_init()"/>
|
||||
|
||||
<periodic fun="opticflow_module_run()" start="opticflow_module_start()" stop="opticflow_module_stop()" autorun="TRUE"/>
|
||||
<makefile target="ap">
|
||||
<define name="ARDRONE_VIDEO_PORT" value="2002" />
|
||||
|
||||
<file name="opticflow_module.c"/>
|
||||
<file name="opticflow_thread.c" dir="modules/computer_vision/opticflow"/>
|
||||
<file name="visual_estimator.c" dir="modules/computer_vision/opticflow"/>
|
||||
<file name="hover_stabilization.c" dir="modules/computer_vision/opticflow"/>
|
||||
<file name="optic_flow_int.c" dir="modules/computer_vision/cv/opticflow"/>
|
||||
<file name="fastRosten.c" dir="modules/computer_vision/cv/opticflow/fast9"/>
|
||||
<file name="trig.c" dir="modules/computer_vision/cv"/>
|
||||
<file name="framerate.c" dir="modules/computer_vision/cv"/>
|
||||
<file name="jpeg.c" dir="modules/computer_vision/cv/encoding"/>
|
||||
<file name="rtp.c" dir="modules/computer_vision/cv/encoding"/>
|
||||
<file name="socket.c" dir="modules/computer_vision/lib/udp"/>
|
||||
<file name="video.c" dir="modules/computer_vision/lib/v4l"/>
|
||||
<define name="modules/computer_vision/cv" type="include"/>
|
||||
<define name="modules/computer_vision/lib" type="include"/>
|
||||
<define name="pthread" type="raw"/>
|
||||
<define name="__USE_GNU"/>
|
||||
<flag name="LDFLAGS" value="pthread"/>
|
||||
<flag name="LDFLAGS" value="lrt"/>
|
||||
<flag name="LDFLAGS" value="static"/>
|
||||
</makefile>
|
||||
<makefile target="nps">
|
||||
<file name="viewvideo_nps.c"/>
|
||||
</makefile>
|
||||
|
||||
</module>
|
||||
|
||||
@@ -423,6 +423,11 @@ void autopilot_set_mode(uint8_t new_autopilot_mode)
|
||||
case AP_MODE_NAV:
|
||||
guidance_h_mode_changed(GUIDANCE_H_MODE_NAV);
|
||||
break;
|
||||
case AP_MODE_MODULE:
|
||||
#ifdef GUIDANCE_H_MODE_MODULE_SETTING
|
||||
guidance_h_mode_changed(GUIDANCE_H_MODE_MODULE_SETTING);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -464,6 +469,11 @@ void autopilot_set_mode(uint8_t new_autopilot_mode)
|
||||
case AP_MODE_NAV:
|
||||
guidance_v_mode_changed(GUIDANCE_V_MODE_NAV);
|
||||
break;
|
||||
case AP_MODE_MODULE:
|
||||
#ifdef GUIDANCE_V_MODE_MODULE_SETTING
|
||||
guidance_v_mode_changed(GUIDANCE_V_MODE_MODULE_SETTING);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define AP_MODE_RC_DIRECT 14 // Safety Pilot Direct Commands for helicopter direct control
|
||||
#define AP_MODE_CARE_FREE_DIRECT 15
|
||||
#define AP_MODE_FORWARD 16
|
||||
#define AP_MODE_MODULE 17
|
||||
|
||||
extern uint8_t autopilot_mode;
|
||||
extern uint8_t autopilot_mode_auto2;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "generated/airframe.h"
|
||||
|
||||
#include "firmwares/rotorcraft/guidance/guidance_h.h"
|
||||
#include "firmwares/rotorcraft/guidance/guidance_module.h"
|
||||
#include "firmwares/rotorcraft/stabilization.h"
|
||||
#include "firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.h"
|
||||
#include "firmwares/rotorcraft/navigation.h"
|
||||
@@ -252,6 +253,12 @@ void guidance_h_mode_changed(uint8_t new_mode)
|
||||
stabilization_attitude_enter();
|
||||
break;
|
||||
|
||||
#if GUIDANCE_H_MODE_MODULE_SETTING == GUIDANCE_H_MODE_MODULE
|
||||
case GUIDANCE_H_MODE_MODULE:
|
||||
guidance_h_module_enter();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GUIDANCE_H_MODE_NAV:
|
||||
guidance_h_nav_enter();
|
||||
#if NO_ATTITUDE_RESET_ON_MODE_CHANGE
|
||||
@@ -304,6 +311,12 @@ void guidance_h_read_rc(bool_t in_flight)
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if GUIDANCE_H_MODE_MODULE_SETTING == GUIDANCE_H_MODE_MODULE
|
||||
case GUIDANCE_H_MODE_MODULE:
|
||||
guidance_h_module_read_rc();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GUIDANCE_H_MODE_NAV:
|
||||
if (radio_control.status == RC_OK) {
|
||||
stabilization_attitude_read_rc_setpoint_eulers(&guidance_h_rc_sp, in_flight, FALSE, FALSE);
|
||||
@@ -387,6 +400,12 @@ void guidance_h_run(bool_t in_flight)
|
||||
stabilization_attitude_run(in_flight);
|
||||
break;
|
||||
|
||||
#if GUIDANCE_H_MODE_MODULE_SETTING == GUIDANCE_H_MODE_MODULE
|
||||
case GUIDANCE_H_MODE_MODULE:
|
||||
guidance_h_module_run(in_flight);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define GUIDANCE_H_MODE_RC_DIRECT 5
|
||||
#define GUIDANCE_H_MODE_CARE_FREE 6
|
||||
#define GUIDANCE_H_MODE_FORWARD 7
|
||||
#define GUIDANCE_H_MODE_MODULE 8
|
||||
|
||||
|
||||
extern uint8_t guidance_h_mode;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2015
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file firmwares/rotorcraft/guidance/guidance_module.h
|
||||
* Guidance in a module file.
|
||||
*
|
||||
* Implement a custom controller in a module.
|
||||
* Re-use desired modes:
|
||||
*
|
||||
* e.g.: <tt>#define GUIDANCE_V_MODE_MODULE_SETTING GUIDANCE_V_MODE_HOVER</tt>
|
||||
* can be used to only define a horizontal control in the module and use normal z_hold
|
||||
*
|
||||
* The guidance that the module implement must be activated with following defines:
|
||||
*
|
||||
* a) Implement own Horizontal loops when GUIDANCE_H_MODE_MODULE_SETTING is set to GUIDANCE_H_MODE_MODULE
|
||||
* One must then implement:
|
||||
* - void guidance_h_module_enter(void);
|
||||
* - void guidance_h_module_read_rc(void);
|
||||
* - void guidance_h_module_run(bool_t in_flight);
|
||||
*
|
||||
*
|
||||
* b) Implement own Vertical loops when GUIDANCE_V_MODE_MODULE_SETTING is set to GUIDANCE_V_MODE_MODULE
|
||||
* - void guidance_v_module_enter(void);
|
||||
* - void guidance_v_module_run(bool_t in_flight);
|
||||
*
|
||||
* If the module implements both V and H mode, take into account that the H is called first and later V
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GUIDANCE_MODULE_H_
|
||||
#define GUIDANCE_MODULE_H_
|
||||
|
||||
#include "generated/modules.h"
|
||||
|
||||
|
||||
#endif /* GUIDANCE_MODULE_H_ */
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "generated/airframe.h"
|
||||
#include "firmwares/rotorcraft/guidance/guidance_v.h"
|
||||
#include "firmwares/rotorcraft/guidance/guidance_module.h"
|
||||
|
||||
#include "subsystems/radio_control.h"
|
||||
#include "firmwares/rotorcraft/stabilization.h"
|
||||
@@ -237,6 +238,12 @@ void guidance_v_mode_changed(uint8_t new_mode)
|
||||
GuidanceVSetRef(stateGetPositionNed_i()->z, stateGetSpeedNed_i()->z, 0);
|
||||
break;
|
||||
|
||||
#if GUIDANCE_V_MODE_MODULE_SETTING == GUIDANCE_V_MODE_MODULE
|
||||
case GUIDANCE_V_MODE_MODULE:
|
||||
guidance_v_module_enter();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -307,6 +314,12 @@ void guidance_v_run(bool_t in_flight)
|
||||
stabilization_cmd[COMMAND_THRUST] = guidance_v_delta_t;
|
||||
break;
|
||||
|
||||
#if GUIDANCE_V_MODE_MODULE_SETTING == GUIDANCE_V_MODE_MODULE
|
||||
case GUIDANCE_V_MODE_MODULE:
|
||||
guidance_v_module_run(in_flight);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GUIDANCE_V_MODE_NAV: {
|
||||
if (vertical_mode == VERTICAL_MODE_ALT) {
|
||||
guidance_v_z_sp = -nav_flight_altitude;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define GUIDANCE_V_MODE_CLIMB 3
|
||||
#define GUIDANCE_V_MODE_HOVER 4
|
||||
#define GUIDANCE_V_MODE_NAV 5
|
||||
#define GUIDANCE_V_MODE_MODULE 6
|
||||
|
||||
extern uint8_t guidance_v_mode;
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Paparazzi Community
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/cv/framerate.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
#include "framerate.h"
|
||||
|
||||
// Frame Rate (FPS)
|
||||
#include <sys/time.h>
|
||||
|
||||
// local variables
|
||||
volatile long timestamp;
|
||||
struct timeval start_time;
|
||||
struct timeval end_time;
|
||||
|
||||
#define USEC_PER_SEC 1000000L
|
||||
|
||||
static long time_elapsed(struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
long sec, usec;
|
||||
sec = t2->tv_sec - t1->tv_sec;
|
||||
usec = t2->tv_usec - t1->tv_usec;
|
||||
if (usec < 0) {
|
||||
--sec;
|
||||
usec = usec + USEC_PER_SEC;
|
||||
}
|
||||
return sec * USEC_PER_SEC + usec;
|
||||
}
|
||||
|
||||
static void start_timer(void)
|
||||
{
|
||||
gettimeofday(&start_time, NULL);
|
||||
}
|
||||
|
||||
static long end_timer(void)
|
||||
{
|
||||
gettimeofday(&end_time, NULL);
|
||||
return time_elapsed(&start_time, &end_time);
|
||||
}
|
||||
|
||||
|
||||
void framerate_init(void) {
|
||||
// Frame Rate Initialization
|
||||
timestamp = 0;
|
||||
start_timer();
|
||||
}
|
||||
|
||||
float framerate_run(void) {
|
||||
// FPS
|
||||
timestamp = end_timer();
|
||||
float framerate_FPS = (float) 1000000 / (float)timestamp;
|
||||
// printf("dt = %d, FPS = %f\n",timestamp, FPS);
|
||||
start_timer();
|
||||
return framerate_FPS;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Paparazzi Community
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/cv/framerate.h
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void framerate_init(void);
|
||||
float framerate_run(void);
|
||||
@@ -0,0 +1,30 @@
|
||||
Copyright(c) 2006, 2008 Edward Rosten
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
|
||||
*Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
*Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and / or other materials provided with the distribution.
|
||||
|
||||
*Neither the name of the University of Cambridge nor the names of
|
||||
its contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2006, 2008 Edward Rosten
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
|
||||
*Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
*Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
*Neither the name of the University of Cambridge nor the names of
|
||||
its contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FAST_H
|
||||
#define FAST_H
|
||||
|
||||
typedef struct { int x, y; } xyFAST;
|
||||
typedef unsigned char byte;
|
||||
|
||||
int fast9_corner_score(const byte *p, const int pixel[], int bstart);
|
||||
|
||||
xyFAST *fast9_detect(const byte *im, int xsize, int ysize, int stride, int b, int *ret_num_corners);
|
||||
|
||||
int *fast9_score(const byte *i, int stride, xyFAST *corners, int num_corners, int b);
|
||||
|
||||
xyFAST *fast9_detect_nonmax(const byte *im, int xsize, int ysize, int stride, int b, int *ret_num_corners);
|
||||
|
||||
xyFAST *nonmax_suppression(const xyFAST *corners, const int *scores, int num_corners, int *ret_num_nonmax);
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2014
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/cv/opticflow/optic_flow_int.h
|
||||
* @brief efficient fixed-point optical-flow
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPTIC_FLOW_INT_H
|
||||
#define OPTIC_FLOW_INT_H
|
||||
|
||||
void multiplyImages(int *ImA, int *ImB, int *ImC, int width, int height);
|
||||
void getImageDifference(int *ImA, int *ImB, int *ImC, int width, int height);
|
||||
void getSubPixel_gray(int *Patch, unsigned char *frame_buf, int center_x, int center_y, int half_window_size,
|
||||
int subpixel_factor);
|
||||
void getGradientPatch(int *Patch, int *DX, int *DY, int half_window_size);
|
||||
int getSumPatch(int *Patch, int size);
|
||||
int calculateG(int *G, int *DX, int *DY, int half_window_size);
|
||||
int calculateError(int *ImC, int width, int height);
|
||||
int opticFlowLK(unsigned char *new_image_buf, unsigned char *old_image_buf, int *p_x, int *p_y, int n_found_points,
|
||||
int imW, int imH, int *new_x, int *new_y, int *status, int half_window_size, int max_iterations);
|
||||
void quick_sort(float *a, int n);
|
||||
void quick_sort_int(int *a, int n);
|
||||
void CvtYUYV2Gray(unsigned char *grayframe, unsigned char *frame, int imW, int imH);
|
||||
void OFfilter(float *OFx, float *OFy, float dx, float dy, int count, int OF_FilterType);
|
||||
|
||||
#endif /* OPTIC_FLOW_INT_H */
|
||||
@@ -23,26 +23,39 @@
|
||||
#include <stdint.h>
|
||||
#include "image.h"
|
||||
|
||||
/** Simplified high-speed low CPU downsample function without averaging
|
||||
*
|
||||
* downsample factor must be 1, 2, 4, 8 ... 2^X
|
||||
* image of typ UYVY expected. Only one color UV per 2 pixels
|
||||
*
|
||||
* we keep the UV color of the first pixel pair
|
||||
* and sample the intensity evenly 1-3-5-7-... or 1-5-9-...
|
||||
*
|
||||
* input: u1y1 v1y2 u3y3 v3y4 u5y5 v5y6 u7y7 v7y8 ...
|
||||
* downsample=1 u1y1 v1y2 u3y3 v3y4 u5y5 v5y6 u7y7 v7y8 ...
|
||||
* downsample=2 u1y1v1 (skip2) y3 (skip2) u5y5v5 (skip2 y7 (skip2) ...
|
||||
* downsample=4 u1y1v1 (skip6) y5 (skip6) ...
|
||||
*/
|
||||
|
||||
inline void resize_uyuv(struct img_struct *input, struct img_struct *output, int downsample);
|
||||
inline void resize_uyuv(struct img_struct *input, struct img_struct *output, int downsample)
|
||||
{
|
||||
uint8_t *source = input->buf;
|
||||
uint8_t *dest = output->buf;
|
||||
|
||||
int pixelskip = downsample - 1;
|
||||
int pixelskip = (downsample - 1) * 2;
|
||||
for (int y = 0; y < output->h; y++) {
|
||||
for (int x = 0; x < output->w; x += 2) {
|
||||
// YUYV
|
||||
*dest++ = *source++; // U
|
||||
*dest++ = *source++; // Y
|
||||
// now skip 3 pixels
|
||||
if (pixelskip) { source += (pixelskip + 1) * 2; }
|
||||
*dest++ = *source++; // U
|
||||
*dest++ = *source++; // V
|
||||
if (pixelskip) { source += (pixelskip - 1) * 2; }
|
||||
source += pixelskip;
|
||||
*dest++ = *source++; // Y
|
||||
source += pixelskip;
|
||||
}
|
||||
// skip 3 rows
|
||||
if (pixelskip) { source += pixelskip * input->w * 2; }
|
||||
// read 1 in every 'downsample' rows, so skip (downsample-1) rows after reading the first
|
||||
source += (downsample-1) * input->w * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Trigonometry
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "trig.h"
|
||||
|
||||
static int cosine[] = {
|
||||
10000, 9998, 9994, 9986, 9976, 9962, 9945, 9925, 9903, 9877,
|
||||
9848, 9816, 9781, 9744, 9703, 9659, 9613, 9563, 9511, 9455,
|
||||
9397, 9336, 9272, 9205, 9135, 9063, 8988, 8910, 8829, 8746,
|
||||
8660, 8572, 8480, 8387, 8290, 8192, 8090, 7986, 7880, 7771,
|
||||
7660, 7547, 7431, 7314, 7193, 7071, 6947, 6820, 6691, 6561,
|
||||
6428, 6293, 6157, 6018, 5878, 5736, 5592, 5446, 5299, 5150,
|
||||
5000, 4848, 4695, 4540, 4384, 4226, 4067, 3907, 3746, 3584,
|
||||
3420, 3256, 3090, 2924, 2756, 2588, 2419, 2250, 2079, 1908,
|
||||
1736, 1564, 1392, 1219, 1045, 872, 698, 523, 349, 175,
|
||||
0
|
||||
};
|
||||
|
||||
int sin_zelf(int ix)
|
||||
{
|
||||
while (ix < 0) {
|
||||
ix = ix + 360;
|
||||
}
|
||||
while (ix >= 360) {
|
||||
ix = ix - 360;
|
||||
}
|
||||
if (ix < 90) { return cosine[90 - ix] / 10; }
|
||||
if (ix < 180) { return cosine[ix - 90] / 10; }
|
||||
if (ix < 270) { return -cosine[270 - ix] / 10; }
|
||||
if (ix < 360) { return -cosine[ix - 270] / 10; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cos_zelf(int ix)
|
||||
{
|
||||
while (ix < 0) {
|
||||
ix = ix + 360;
|
||||
}
|
||||
while (ix >= 360) {
|
||||
ix = ix - 360;
|
||||
}
|
||||
if (ix < 90) { return cosine[ix] / 10; }
|
||||
if (ix < 180) { return -cosine[180 - ix] / 10; }
|
||||
if (ix < 270) { return -cosine[ix - 180] / 10; }
|
||||
if (ix < 360) { return cosine[360 - ix] / 10; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tan_zelf(int ix)
|
||||
{
|
||||
|
||||
while (ix < 0) {
|
||||
ix = ix + 360;
|
||||
}
|
||||
while (ix >= 360) {
|
||||
ix = ix - 360;
|
||||
}
|
||||
if (ix == 90) { return 9999; }
|
||||
if (ix == 270) { return -9999; }
|
||||
if (ix < 90) { return (1000 * cosine[90 - ix]) / cosine[ix]; }
|
||||
if (ix < 180) { return -(1000 * cosine[ix - 90]) / cosine[180 - ix]; }
|
||||
if (ix < 270) { return (1000 * cosine[270 - ix]) / cosine[ix - 180]; }
|
||||
if (ix < 360) { return -(1000 * cosine[ix - 270]) / cosine[360 - ix]; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asin_zelf(int y, int hyp)
|
||||
{
|
||||
int quot, sgn, ix;
|
||||
if ((y > hyp) || (y == 0)) {
|
||||
return 0;
|
||||
}
|
||||
sgn = hyp * y;
|
||||
if (hyp < 0) {
|
||||
hyp = -hyp;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = -y;
|
||||
}
|
||||
quot = (y * 10000) / hyp;
|
||||
if (quot > 9999) {
|
||||
quot = 9999;
|
||||
}
|
||||
for (ix = 0; ix < 90; ix++)
|
||||
if ((quot < cosine[ix]) && (quot >= cosine[ix + 1])) {
|
||||
break;
|
||||
}
|
||||
if (sgn < 0) {
|
||||
return -(90 - ix);
|
||||
} else {
|
||||
return 90 - ix;
|
||||
}
|
||||
}
|
||||
|
||||
int acos_zelf(int x, int hyp)
|
||||
{
|
||||
int quot, sgn, ix;
|
||||
if (x > hyp) {
|
||||
return 0;
|
||||
}
|
||||
if (x == 0) {
|
||||
if (hyp < 0) {
|
||||
return -90;
|
||||
} else {
|
||||
return 90;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sgn = hyp * x;
|
||||
if (hyp < 0) {
|
||||
hyp = -hyp;
|
||||
}
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
}
|
||||
quot = (x * 10000) / hyp;
|
||||
if (quot > 9999) {
|
||||
quot = 9999;
|
||||
}
|
||||
for (ix = 0; ix < 90; ix++)
|
||||
if ((quot < cosine[ix]) && (quot >= cosine[ix + 1])) {
|
||||
break;
|
||||
}
|
||||
if (sgn < 0) {
|
||||
return -ix;
|
||||
} else {
|
||||
return ix;
|
||||
}
|
||||
}
|
||||
|
||||
//atan_zelf(y/x) in degrees
|
||||
int atan_zelf(int y, int x)
|
||||
{
|
||||
int angle, flip, t, xy;
|
||||
|
||||
if (x < 0) { x = -x; }
|
||||
if (y < 0) { y = -y; }
|
||||
flip = 0;
|
||||
if (x < y) { flip = 1; t = x; x = y; y = t; }
|
||||
if (x == 0) { return 90; }
|
||||
|
||||
xy = (y * 1000) / x;
|
||||
angle = (360 * xy) / (6283 + ((((1764 * xy) / 1000) * xy) / 1000));
|
||||
if (flip) { angle = 90 - angle; }
|
||||
return angle;
|
||||
}
|
||||
|
||||
unsigned int isqrt(unsigned int val)
|
||||
{
|
||||
unsigned int temp, g = 0, b = 0x8000, bshft = 15;
|
||||
do {
|
||||
if (val >= (temp = (((g << 1) + b) << bshft--))) {
|
||||
g += b;
|
||||
val -= temp;
|
||||
}
|
||||
} while (b >>= 1);
|
||||
return g;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
int cos_zelf(int ix);
|
||||
int sin_zelf(int);
|
||||
int tan_zelf(int);
|
||||
int acos_zelf(int, int);
|
||||
int asin_zelf(int, int);
|
||||
int atan_zelf(int, int);
|
||||
unsigned int isqrt(unsigned int);
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef _VIDEO_H
|
||||
#define _VIDEO_H
|
||||
|
||||
#include "../../cv/image.h"
|
||||
#include "modules/computer_vision/cv/image.h"
|
||||
|
||||
struct buffer_struct {
|
||||
void *buf;
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/hover_stabilization.c
|
||||
* @brief optical-flow based hovering for Parrot AR.Drone 2.0
|
||||
*
|
||||
* Control loops for optic flow based hovering.
|
||||
* Computes setpoint for the lower level attitude stabilization to control horizontal velocity.
|
||||
*/
|
||||
|
||||
// Own Header
|
||||
#include "hover_stabilization.h"
|
||||
|
||||
// Stabilization
|
||||
#include "firmwares/rotorcraft/stabilization/stabilization_attitude.h"
|
||||
#include "firmwares/rotorcraft/guidance/guidance_v.h"
|
||||
#include "autopilot.h"
|
||||
|
||||
// Downlink
|
||||
#include "subsystems/datalink/downlink.h"
|
||||
|
||||
// Controller Gains
|
||||
/* error if some gains are negative */
|
||||
#if (VISION_PHI_PGAIN < 0) || \
|
||||
(VISION_PHI_IGAIN < 0) || \
|
||||
(VISION_THETA_PGAIN < 0) || \
|
||||
(VISION_THETA_IGAIN < 0)
|
||||
#error "ALL control gains have to be positive!!!"
|
||||
#endif
|
||||
bool activate_opticflow_hover;
|
||||
float vision_desired_vx;
|
||||
float vision_desired_vy;
|
||||
int32_t vision_phi_pgain;
|
||||
int32_t vision_phi_igain;
|
||||
int32_t vision_theta_pgain;
|
||||
int32_t vision_theta_igain;
|
||||
|
||||
// Controller Commands
|
||||
struct Int32Eulers cmd_euler;
|
||||
|
||||
// Hover Stabilization
|
||||
float Velx_Int;
|
||||
float Vely_Int;
|
||||
float Error_Velx;
|
||||
float Error_Vely;
|
||||
|
||||
#define CMD_OF_SAT 1500 // 40 deg = 2859.1851
|
||||
unsigned char saturateX = 0, saturateY = 0;
|
||||
unsigned int set_heading;
|
||||
|
||||
|
||||
#ifndef VISION_HOVER
|
||||
#define VISION_HOVER TRUE
|
||||
#endif
|
||||
|
||||
#ifndef VISION_PHI_PGAIN
|
||||
#define VISION_PHI_PGAIN 500.
|
||||
#endif
|
||||
|
||||
#ifndef VISION_PHI_IGAIN
|
||||
#define VISION_PHI_IGAIN 10.
|
||||
#endif
|
||||
|
||||
#ifndef VISION_THETA_PGAIN
|
||||
#define VISION_THETA_PGAIN 500.
|
||||
#endif
|
||||
|
||||
#ifndef VISION_THETA_IGAIN
|
||||
#define VISION_THETA_IGAIN 10.
|
||||
#endif
|
||||
|
||||
#ifndef VISION_DESIRED_VX
|
||||
#define VISION_DESIRED_VX 0.
|
||||
#endif
|
||||
|
||||
#ifndef VISION_DESIRED_VY
|
||||
#define VISION_DESIRED_VY 0.
|
||||
#endif
|
||||
|
||||
void run_opticflow_hover(void);
|
||||
|
||||
void guidance_h_module_enter(void)
|
||||
{
|
||||
// INIT
|
||||
Velx_Int = 0;
|
||||
Vely_Int = 0;
|
||||
// GUIDANCE: Set Hover-z-hold
|
||||
guidance_v_z_sp = -1;
|
||||
}
|
||||
|
||||
void guidance_h_module_read_rc(void)
|
||||
{
|
||||
// Do not read RC
|
||||
// Setpoint being set by vision
|
||||
}
|
||||
|
||||
void guidance_h_module_run(bool_t in_flight)
|
||||
{
|
||||
// Run
|
||||
// Setpoint being set by vision
|
||||
stabilization_attitude_run(in_flight);
|
||||
}
|
||||
|
||||
|
||||
void init_hover_stabilization_onvision()
|
||||
{
|
||||
INT_EULERS_ZERO(cmd_euler);
|
||||
|
||||
activate_opticflow_hover = VISION_HOVER;
|
||||
vision_phi_pgain = VISION_PHI_PGAIN;
|
||||
vision_phi_igain = VISION_PHI_IGAIN;
|
||||
vision_theta_pgain = VISION_THETA_PGAIN;
|
||||
vision_theta_igain = VISION_THETA_IGAIN;
|
||||
vision_desired_vx = VISION_DESIRED_VX;
|
||||
vision_desired_vy = VISION_DESIRED_VY;
|
||||
|
||||
set_heading = 1;
|
||||
|
||||
Error_Velx = 0;
|
||||
Error_Vely = 0;
|
||||
Velx_Int = 0;
|
||||
Vely_Int = 0;
|
||||
}
|
||||
|
||||
void run_hover_stabilization_onvision(struct CVresults* vision )
|
||||
{
|
||||
struct FloatVect3 V_body;
|
||||
if (activate_opticflow_hover == TRUE) {
|
||||
// Compute body velocities from ENU
|
||||
struct FloatVect3 *vel_ned = (struct FloatVect3*)stateGetSpeedNed_f();
|
||||
struct FloatQuat *q_n2b = stateGetNedToBodyQuat_f();
|
||||
float_quat_vmult(&V_body, q_n2b, vel_ned);
|
||||
}
|
||||
|
||||
// *************************************************************************************
|
||||
// Downlink Message
|
||||
// *************************************************************************************
|
||||
|
||||
DOWNLINK_SEND_OF_HOVER(DefaultChannel, DefaultDevice,
|
||||
&vision->FPS, &vision->dx_sum, &vision->dy_sum, &vision->OFx, &vision->OFy,
|
||||
&vision->diff_roll, &vision->diff_pitch,
|
||||
&vision->Velx, &vision->Vely,
|
||||
&V_body.x, &V_body.y,
|
||||
&vision->cam_h, &vision->count);
|
||||
|
||||
if (autopilot_mode != AP_MODE_MODULE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vision->flow_count) {
|
||||
Error_Velx = vision->Velx - vision_desired_vx;
|
||||
Error_Vely = vision->Vely - vision_desired_vy;
|
||||
} else {
|
||||
Error_Velx = 0;
|
||||
Error_Vely = 0;
|
||||
}
|
||||
|
||||
if (saturateX == 0) {
|
||||
if (activate_opticflow_hover == TRUE) {
|
||||
Velx_Int += vision_theta_igain * Error_Velx;
|
||||
} else {
|
||||
Velx_Int += vision_theta_igain * V_body.x;
|
||||
}
|
||||
}
|
||||
if (saturateY == 0) {
|
||||
if (activate_opticflow_hover == TRUE) {
|
||||
Vely_Int += vision_phi_igain * Error_Vely;
|
||||
} else {
|
||||
Vely_Int += vision_phi_igain * V_body.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_heading) {
|
||||
cmd_euler.psi = stateGetNedToBodyEulers_i()->psi;
|
||||
set_heading = 0;
|
||||
}
|
||||
|
||||
if (activate_opticflow_hover == TRUE) {
|
||||
cmd_euler.phi = - (vision_phi_pgain * Error_Vely + Vely_Int);
|
||||
cmd_euler.theta = (vision_theta_pgain * Error_Velx + Velx_Int);
|
||||
} else {
|
||||
cmd_euler.phi = - (vision_phi_pgain * V_body.y + Vely_Int);
|
||||
cmd_euler.theta = (vision_theta_pgain * V_body.x + Velx_Int);
|
||||
}
|
||||
|
||||
saturateX = 0; saturateY = 0;
|
||||
if (cmd_euler.phi < -CMD_OF_SAT) {cmd_euler.phi = -CMD_OF_SAT; saturateX = 1;}
|
||||
else if (cmd_euler.phi > CMD_OF_SAT) {cmd_euler.phi = CMD_OF_SAT; saturateX = 1;}
|
||||
if (cmd_euler.theta < -CMD_OF_SAT) {cmd_euler.theta = -CMD_OF_SAT; saturateY = 1;}
|
||||
else if (cmd_euler.theta > CMD_OF_SAT) {cmd_euler.theta = CMD_OF_SAT; saturateY = 1;}
|
||||
|
||||
stabilization_attitude_set_rpy_setpoint_i(&cmd_euler);
|
||||
DOWNLINK_SEND_VISION_STABILIZATION(DefaultChannel, DefaultDevice, &vision->Velx, &vision->Vely, &Velx_Int,
|
||||
&Vely_Int, &cmd_euler.phi, &cmd_euler.theta);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/hover_stabilization.h
|
||||
* @brief optical-flow based hovering for Parrot AR.Drone 2.0
|
||||
*
|
||||
* Control loops for optic flow based hovering.
|
||||
* Computes setpoint for the lower level attitude stabilization to control horizontal velocity.
|
||||
*/
|
||||
|
||||
#ifndef HOVER_STABILIZATION_H_
|
||||
#define HOVER_STABILIZATION_H_
|
||||
|
||||
#include <std.h>
|
||||
#include "inter_thread_data.h"
|
||||
|
||||
// Controller module
|
||||
|
||||
// Vertical loop re-uses Alt-hold
|
||||
#define GUIDANCE_V_MODE_MODULE_SETTING GUIDANCE_V_MODE_HOVER
|
||||
|
||||
// Horizontal mode is a specific controller
|
||||
#define GUIDANCE_H_MODE_MODULE_SETTING GUIDANCE_H_MODE_MODULE
|
||||
|
||||
// Implement own Horizontal loops
|
||||
extern void guidance_h_module_enter(void);
|
||||
extern void guidance_h_module_read_rc(void);
|
||||
extern void guidance_h_module_run(bool_t in_flight);
|
||||
|
||||
|
||||
void init_hover_stabilization_onvision(void);
|
||||
void run_hover_stabilization_onvision(struct CVresults *vision);
|
||||
|
||||
extern bool activate_opticflow_hover;
|
||||
extern float vision_desired_vx;
|
||||
extern float vision_desired_vy;
|
||||
extern int32_t vision_phi_pgain;
|
||||
extern int32_t vision_phi_igain;
|
||||
extern int32_t vision_theta_pgain;
|
||||
extern int32_t vision_theta_igain;
|
||||
|
||||
#endif /* HOVER_STABILIZATION_H_ */
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Paparazzi Community
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/inter_thread_data.h
|
||||
* @brief Inter-thread data structures.
|
||||
*
|
||||
* Data structures used to for inter-thread communication via Unix Domain sockets.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _INTER_THREAD_DATA_H
|
||||
#define _INTER_THREAD_DATA_H
|
||||
|
||||
/// Data from thread to module
|
||||
struct CVresults {
|
||||
int cnt; // Number of processed frames
|
||||
|
||||
float Velx; // Velocity as measured by camera
|
||||
float Vely;
|
||||
int flow_count;
|
||||
|
||||
float cam_h; // Debug parameters
|
||||
int count;
|
||||
float OFx, OFy, dx_sum, dy_sum;
|
||||
float diff_roll;
|
||||
float diff_pitch;
|
||||
float FPS;
|
||||
};
|
||||
|
||||
/// Data from module to thread
|
||||
struct PPRZinfo {
|
||||
int cnt; // IMU msg counter
|
||||
float phi; // roll [rad]
|
||||
float theta; // pitch [rad]
|
||||
float agl; // height above ground [m]
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Paparazzi Community
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/opticflow_thread.c
|
||||
*
|
||||
*/
|
||||
|
||||
// Sockets
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "opticflow_thread.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// COMPUTER VISION THREAD
|
||||
|
||||
// Video
|
||||
#include "v4l/video.h"
|
||||
#include "resize.h"
|
||||
|
||||
// Payload Code
|
||||
#include "visual_estimator.h"
|
||||
|
||||
// Downlink Video
|
||||
//#define DOWNLINK_VIDEO 1
|
||||
|
||||
#ifdef DOWNLINK_VIDEO
|
||||
#include "encoding/jpeg.h"
|
||||
#include "encoding/rtp.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#define DEBUG_INFO(X, ...) ;
|
||||
|
||||
static volatile enum{RUN,EXIT} computer_vision_thread_command = RUN; /** request to close: set to 1 */
|
||||
|
||||
void computervision_thread_request_exit(void) {
|
||||
computer_vision_thread_command = EXIT;
|
||||
}
|
||||
|
||||
void *computervision_thread_main(void *args)
|
||||
{
|
||||
int thread_socket = *(int *) args;
|
||||
|
||||
// Local data in/out
|
||||
struct CVresults vision_results;
|
||||
struct PPRZinfo autopilot_data;
|
||||
|
||||
// Status
|
||||
computer_vision_thread_command = RUN;
|
||||
|
||||
// Video Input
|
||||
struct vid_struct vid;
|
||||
/* On ARDrone2:
|
||||
* video1 = front camera; video2 = bottom camera
|
||||
*/
|
||||
vid.device = (char *)"/dev/video2";
|
||||
vid.w = 320;
|
||||
vid.h = 240;
|
||||
vid.n_buffers = 4;
|
||||
|
||||
if (video_init(&vid) < 0) {
|
||||
printf("Error initialising video\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Video Grabbing
|
||||
struct img_struct *img_new = video_create_image(&vid);
|
||||
|
||||
#ifdef DOWNLINK_VIDEO
|
||||
// Video Compression
|
||||
uint8_t *jpegbuf = (uint8_t *)malloc(vid.h * vid.w * 2);
|
||||
|
||||
// Network Transmit
|
||||
struct UdpSocket *vsock;
|
||||
//#define FMS_UNICAST 0
|
||||
//#define FMS_BROADCAST 1
|
||||
vsock = udp_socket("192.168.1.255", 5000, 5001, FMS_BROADCAST);
|
||||
#endif
|
||||
|
||||
// First Apply Settings before init
|
||||
opticflow_plugin_init(vid.w, vid.h, &vision_results);
|
||||
|
||||
while (computer_vision_thread_command == RUN) {
|
||||
|
||||
// Wait for a new frame
|
||||
video_grab_image(&vid, img_new);
|
||||
|
||||
// Get most recent State information
|
||||
int bytes_read = sizeof(autopilot_data);
|
||||
while (bytes_read == sizeof(autopilot_data))
|
||||
{
|
||||
bytes_read = recv(thread_socket, &autopilot_data, sizeof(autopilot_data), MSG_DONTWAIT);
|
||||
if (bytes_read != sizeof(autopilot_data)) {
|
||||
if (bytes_read != -1) {
|
||||
printf("[thread] Failed to read %d bytes PPRZ info from socket.\n",bytes_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG_INFO("[thread] Read # %d\n",autopilot_data.cnt);
|
||||
|
||||
// Run Image Processing with image and data and get results
|
||||
opticflow_plugin_run(img_new->buf, &autopilot_data, &vision_results);
|
||||
|
||||
/* Send results to main */
|
||||
vision_results.cnt++;
|
||||
int bytes_written = write(thread_socket, &vision_results, sizeof(vision_results));
|
||||
if (bytes_written != sizeof(vision_results)){
|
||||
perror("[thread] Failed to write to socket.\n");
|
||||
}
|
||||
DEBUG_INFO("[thread] Write # %d, (bytes %d)\n",vision_results.cnt, bytes_written);
|
||||
|
||||
#ifdef DOWNLINK_VIDEO
|
||||
// JPEG encode the image:
|
||||
uint32_t quality_factor = 10; //20 if no resize,
|
||||
uint8_t dri_header = 0;
|
||||
uint32_t image_format = FOUR_TWO_TWO; // format (in jpeg.h)
|
||||
uint8_t *end = encode_image(small.buf, jpegbuf, quality_factor, image_format, small.w, small.h, dri_header);
|
||||
uint32_t size = end - (jpegbuf);
|
||||
|
||||
printf("Sending an image ...%u\n", size);
|
||||
send_rtp_frame(vsock, jpegbuf, size, small.w, small.h, 0, quality_factor, dri_header, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("Thread Closed\n");
|
||||
video_close(&vid);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Paparazzi Community
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/opticflow_thread.h
|
||||
* @brief computer vision thread
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPTICFLOW_THREAD_H
|
||||
#define OPTICFLOW_THREAD_H
|
||||
|
||||
void *computervision_thread_main(void *args); /* computer vision thread: should be given a pointer to a socketpair as argument */
|
||||
void computervision_thread_request_exit(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/visual_estimator.c
|
||||
* @brief Estimate velocity from optic flow.
|
||||
*
|
||||
* Using sensors from vertical camera and IMU of Parrot AR.Drone 2.0.
|
||||
*
|
||||
* Warning: all this code is called form the Vision-Thread: do not access any autopilot data in here.
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Own Header
|
||||
#include "visual_estimator.h"
|
||||
|
||||
// Computer Vision
|
||||
#include "opticflow/optic_flow_int.h"
|
||||
#include "opticflow/fast9/fastRosten.h"
|
||||
|
||||
// for FPS
|
||||
#include "modules/computer_vision/cv/framerate.h"
|
||||
|
||||
|
||||
// Local variables
|
||||
struct visual_estimator_struct
|
||||
{
|
||||
// Image size
|
||||
unsigned int imgWidth;
|
||||
unsigned int imgHeight;
|
||||
|
||||
// Images
|
||||
uint8_t *prev_frame;
|
||||
uint8_t *gray_frame;
|
||||
uint8_t *prev_gray_frame;
|
||||
|
||||
// Initialization
|
||||
int old_img_init;
|
||||
|
||||
// Store previous
|
||||
float prev_pitch;
|
||||
float prev_roll;
|
||||
} visual_estimator;
|
||||
|
||||
// ARDrone Vertical Camera Parameters
|
||||
#define FOV_H 0.67020643276
|
||||
#define FOV_W 0.89360857702
|
||||
#define Fx_ARdrone 343.1211
|
||||
#define Fy_ARdrone 348.5053
|
||||
|
||||
// Corner Detection
|
||||
#define MAX_COUNT 100
|
||||
|
||||
// Flow Derotation
|
||||
#define FLOW_DEROTATION
|
||||
|
||||
|
||||
// Called by plugin
|
||||
void opticflow_plugin_init(unsigned int w, unsigned int h, struct CVresults *results)
|
||||
{
|
||||
// Initialize variables
|
||||
visual_estimator.imgWidth = w;
|
||||
visual_estimator.imgHeight = h;
|
||||
|
||||
visual_estimator.gray_frame = (unsigned char *) calloc(w * h, sizeof(uint8_t));
|
||||
visual_estimator.prev_frame = (unsigned char *) calloc(w * h * 2, sizeof(uint8_t));
|
||||
visual_estimator.prev_gray_frame = (unsigned char *) calloc(w * h, sizeof(uint8_t));
|
||||
|
||||
visual_estimator.old_img_init = 1;
|
||||
visual_estimator.prev_pitch = 0.0;
|
||||
visual_estimator.prev_roll = 0.0;
|
||||
|
||||
results->OFx = 0.0;
|
||||
results->OFy = 0.0;
|
||||
results->dx_sum = 0.0;
|
||||
results->dy_sum = 0.0;
|
||||
results->diff_roll = 0.0;
|
||||
results->diff_pitch = 0.0;
|
||||
results->cam_h = 0.0;
|
||||
results->Velx = 0.0;
|
||||
results->Vely = 0.0;
|
||||
results->flow_count = 0;
|
||||
results->cnt = 0;
|
||||
results->count = 0;
|
||||
|
||||
framerate_init();
|
||||
}
|
||||
|
||||
void opticflow_plugin_run(unsigned char *frame, struct PPRZinfo* info, struct CVresults *results)
|
||||
{
|
||||
// Corner Tracking
|
||||
// Working Variables
|
||||
int max_count = 25;
|
||||
int borderx = 24, bordery = 24;
|
||||
int x[MAX_COUNT], y[MAX_COUNT];
|
||||
int new_x[MAX_COUNT], new_y[MAX_COUNT];
|
||||
int status[MAX_COUNT];
|
||||
int dx[MAX_COUNT], dy[MAX_COUNT];
|
||||
int w = visual_estimator.imgWidth;
|
||||
int h = visual_estimator.imgHeight;
|
||||
|
||||
// Framerate Measuring
|
||||
results->FPS = framerate_run();
|
||||
|
||||
if (visual_estimator.old_img_init == 1) {
|
||||
memcpy(visual_estimator.prev_frame, frame, w * h * 2);
|
||||
CvtYUYV2Gray(visual_estimator.prev_gray_frame, visual_estimator.prev_frame, w, h);
|
||||
visual_estimator.old_img_init = 0;
|
||||
}
|
||||
|
||||
// *************************************************************************************
|
||||
// Corner detection
|
||||
// *************************************************************************************
|
||||
|
||||
// FAST corner detection
|
||||
int fast_threshold = 20;
|
||||
xyFAST *pnts_fast;
|
||||
pnts_fast = fast9_detect((const byte *)visual_estimator.prev_gray_frame, w, h, w,
|
||||
fast_threshold, &results->count);
|
||||
if (results->count > MAX_COUNT) { results->count = MAX_COUNT; }
|
||||
for (int i = 0; i < results->count; i++) {
|
||||
x[i] = pnts_fast[i].x;
|
||||
y[i] = pnts_fast[i].y;
|
||||
}
|
||||
free(pnts_fast);
|
||||
|
||||
// Remove neighboring corners
|
||||
const float min_distance = 3;
|
||||
float min_distance2 = min_distance * min_distance;
|
||||
int labelmin[MAX_COUNT];
|
||||
for (int i = 0; i < results->count; i++) {
|
||||
for (int j = i + 1; j < results->count; j++) {
|
||||
// distance squared:
|
||||
float distance2 = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
|
||||
if (distance2 < min_distance2) {
|
||||
labelmin[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count_fil = results->count;
|
||||
for (int i = results->count - 1; i >= 0; i--) {
|
||||
int remove_point = 0;
|
||||
|
||||
if (labelmin[i]) {
|
||||
remove_point = 1;
|
||||
}
|
||||
|
||||
if (remove_point) {
|
||||
for (int c = i; c < count_fil - 1; c++) {
|
||||
x[c] = x[c + 1];
|
||||
y[c] = y[c + 1];
|
||||
}
|
||||
count_fil--;
|
||||
}
|
||||
}
|
||||
|
||||
if (count_fil > max_count) { count_fil = max_count; }
|
||||
results->count = count_fil;
|
||||
|
||||
// *************************************************************************************
|
||||
// Corner Tracking
|
||||
// *************************************************************************************
|
||||
CvtYUYV2Gray(visual_estimator.gray_frame, frame, w, h);
|
||||
|
||||
opticFlowLK(visual_estimator.gray_frame, visual_estimator.prev_gray_frame, x, y,
|
||||
count_fil, w, h, new_x, new_y, status, 5, 100);
|
||||
|
||||
results->flow_count = count_fil;
|
||||
for (int i = count_fil - 1; i >= 0; i--) {
|
||||
int remove_point = 1;
|
||||
|
||||
if (status[i] && !(new_x[i] < borderx || new_x[i] > (w - 1 - borderx) ||
|
||||
new_y[i] < bordery || new_y[i] > (h - 1 - bordery))) {
|
||||
remove_point = 0;
|
||||
}
|
||||
|
||||
if (remove_point) {
|
||||
for (int c = i; c < results->flow_count - 1; c++) {
|
||||
x[c] = x[c + 1];
|
||||
y[c] = y[c + 1];
|
||||
new_x[c] = new_x[c + 1];
|
||||
new_y[c] = new_y[c + 1];
|
||||
}
|
||||
results->flow_count--;
|
||||
}
|
||||
}
|
||||
|
||||
results->dx_sum = 0.0;
|
||||
results->dy_sum = 0.0;
|
||||
|
||||
// Optical Flow Computation
|
||||
for (int i = 0; i < results->flow_count; i++) {
|
||||
dx[i] = new_x[i] - x[i];
|
||||
dy[i] = new_y[i] - y[i];
|
||||
}
|
||||
|
||||
// Median Filter
|
||||
if (results->flow_count) {
|
||||
quick_sort_int(dx, results->flow_count); // 11
|
||||
quick_sort_int(dy, results->flow_count); // 11
|
||||
|
||||
results->dx_sum = (float) dx[results->flow_count / 2];
|
||||
results->dy_sum = (float) dy[results->flow_count / 2];
|
||||
} else {
|
||||
results->dx_sum = 0.0;
|
||||
results->dy_sum = 0.0;
|
||||
}
|
||||
|
||||
// Flow Derotation
|
||||
results->diff_pitch = (info->theta - visual_estimator.prev_pitch) * h / FOV_H;
|
||||
results->diff_roll = (info->phi - visual_estimator.prev_roll) * w / FOV_W;
|
||||
visual_estimator.prev_pitch = info->theta;
|
||||
visual_estimator.prev_roll = info->phi;
|
||||
|
||||
float OFx_trans, OFy_trans;
|
||||
#ifdef FLOW_DEROTATION
|
||||
if (results->flow_count) {
|
||||
OFx_trans = results->dx_sum - results->diff_roll;
|
||||
OFy_trans = results->dy_sum - results->diff_pitch;
|
||||
|
||||
if ((OFx_trans <= 0) != (results->dx_sum <= 0)) {
|
||||
OFx_trans = 0;
|
||||
OFy_trans = 0;
|
||||
}
|
||||
} else {
|
||||
OFx_trans = results->dx_sum;
|
||||
OFy_trans = results->dy_sum;
|
||||
}
|
||||
#else
|
||||
OFx_trans = results->dx_sum;
|
||||
OFy_trans = results->dy_sum;
|
||||
#endif
|
||||
|
||||
// Average Filter
|
||||
OFfilter(&results->OFx, &results->OFy, OFx_trans, OFy_trans, results->flow_count, 1);
|
||||
|
||||
// Velocity Computation
|
||||
if (info->agl < 0.01) {
|
||||
results->cam_h = 0.01;
|
||||
}
|
||||
else {
|
||||
results->cam_h = info->agl;
|
||||
}
|
||||
|
||||
if (results->flow_count) {
|
||||
results->Velx = results->OFy * results->cam_h * results->FPS / Fy_ARdrone + 0.05;
|
||||
results->Vely = -results->OFx * results->cam_h * results->FPS / Fx_ARdrone - 0.1;
|
||||
} else {
|
||||
results->Velx = 0.0;
|
||||
results->Vely = 0.0;
|
||||
}
|
||||
|
||||
// *************************************************************************************
|
||||
// Next Loop Preparation
|
||||
// *************************************************************************************
|
||||
|
||||
memcpy(visual_estimator.prev_frame, frame, w * h * 2);
|
||||
memcpy(visual_estimator.prev_gray_frame, visual_estimator.gray_frame, w * h);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow/visual_estimator.h
|
||||
* @brief Estimate velocity from optic flow.
|
||||
*
|
||||
* Using sensors from vertical camera and IMU of Parrot AR.Drone 2.0
|
||||
*/
|
||||
|
||||
#ifndef VISUAL_ESTIMATOR_H
|
||||
#define VISUAL_ESTIMATOR_H
|
||||
|
||||
#include "inter_thread_data.h"
|
||||
|
||||
/**
|
||||
* Initialize visual estimator.
|
||||
* @param w image width
|
||||
* @param h image height
|
||||
*/
|
||||
void opticflow_plugin_init(unsigned int w, unsigned int h, struct CVresults *results);
|
||||
void opticflow_plugin_run(unsigned char *frame, struct PPRZinfo* info, struct CVresults* results);
|
||||
|
||||
#endif /* VISUAL_ESTIMATOR_H */
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow_module.c
|
||||
* @brief optical-flow based hovering for Parrot AR.Drone 2.0
|
||||
*
|
||||
* Sensors from vertical camera and IMU of Parrot AR.Drone 2.0
|
||||
*/
|
||||
|
||||
|
||||
#include "opticflow_module.h"
|
||||
|
||||
// Computervision Runs in a thread
|
||||
#include "opticflow/opticflow_thread.h"
|
||||
#include "opticflow/inter_thread_data.h"
|
||||
|
||||
// Navigate Based On Vision, needed to call init/run_hover_stabilization_onvision
|
||||
#include "opticflow/hover_stabilization.h"
|
||||
|
||||
// Threaded computer vision
|
||||
#include <pthread.h>
|
||||
|
||||
// Sockets
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int cv_sockets[2];
|
||||
|
||||
// Paparazzi Data
|
||||
#include "state.h"
|
||||
#include "subsystems/abi.h"
|
||||
|
||||
// Downlink
|
||||
#include "subsystems/datalink/downlink.h"
|
||||
|
||||
|
||||
struct PPRZinfo opticflow_module_data;
|
||||
|
||||
/** height above ground level, from ABI
|
||||
* Used for scale computation, negative value means invalid.
|
||||
*/
|
||||
/** default sonar/agl to use in opticflow visual_estimator */
|
||||
#ifndef OPTICFLOW_AGL_ID
|
||||
#define OPTICFLOW_AGL_ID ABI_BROADCAST
|
||||
#endif
|
||||
abi_event agl_ev;
|
||||
static void agl_cb(uint8_t sender_id, const float *distance);
|
||||
|
||||
static void agl_cb(uint8_t sender_id __attribute__((unused)), const float *distance)
|
||||
{
|
||||
if (*distance > 0) {
|
||||
opticflow_module_data.agl = *distance;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEBUG_INFO(X, ...) ;
|
||||
|
||||
void opticflow_module_init(void)
|
||||
{
|
||||
// get AGL from sonar via ABI
|
||||
AbiBindMsgAGL(OPTICFLOW_AGL_ID, &agl_ev, agl_cb);
|
||||
|
||||
// Initialize local data
|
||||
opticflow_module_data.cnt = 0;
|
||||
opticflow_module_data.phi = 0;
|
||||
opticflow_module_data.theta = 0;
|
||||
opticflow_module_data.agl = 0;
|
||||
|
||||
// Stabilization Code Initialization
|
||||
init_hover_stabilization_onvision();
|
||||
}
|
||||
|
||||
|
||||
void opticflow_module_run(void)
|
||||
{
|
||||
// Send Updated data to thread
|
||||
opticflow_module_data.cnt++;
|
||||
opticflow_module_data.phi = stateGetNedToBodyEulers_f()->phi;
|
||||
opticflow_module_data.theta = stateGetNedToBodyEulers_f()->theta;
|
||||
int bytes_written = write(cv_sockets[0], &opticflow_module_data, sizeof(opticflow_module_data));
|
||||
if (bytes_written != sizeof(opticflow_module_data)){
|
||||
printf("[module] Failed to write to socket: written = %d, error=%d.\n",bytes_written, errno);
|
||||
}
|
||||
else {
|
||||
DEBUG_INFO("[module] Write # %d (%d bytes)\n",opticflow_module_data.cnt, bytes_written);
|
||||
}
|
||||
|
||||
// Read Latest Vision Module Results
|
||||
struct CVresults vision_results;
|
||||
// Warning: if the vision runs faster than the module, you need to read multiple times
|
||||
int bytes_read = recv(cv_sockets[0], &vision_results, sizeof(vision_results), MSG_DONTWAIT);
|
||||
if (bytes_read != sizeof(vision_results)) {
|
||||
if (bytes_read != -1) {
|
||||
printf("[module] Failed to read %d bytes: CV results from socket errno=%d.\n",bytes_read, errno);
|
||||
}
|
||||
} else {
|
||||
////////////////////////////////////////////
|
||||
// Module-Side Code
|
||||
////////////////////////////////////////////
|
||||
DEBUG_INFO("[module] Read vision %d\n",vision_results.cnt);
|
||||
run_hover_stabilization_onvision(&vision_results);
|
||||
}
|
||||
}
|
||||
|
||||
void opticflow_module_start(void)
|
||||
{
|
||||
pthread_t computervision_thread;
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, cv_sockets) == 0) {
|
||||
////////////////////////////////////////////
|
||||
// Thread-Side Code
|
||||
////////////////////////////////////////////
|
||||
int rc = pthread_create(&computervision_thread, NULL, computervision_thread_main,
|
||||
&cv_sockets[1]);
|
||||
if (rc) {
|
||||
printf("ctl_Init: Return code from pthread_create(mot_thread) is %d\n", rc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
perror("Could not create socket.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void opticflow_module_stop(void)
|
||||
{
|
||||
computervision_thread_request_exit();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hann Woei Ho
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/computer_vision/opticflow_module.h
|
||||
* @brief optical-flow based hovering for Parrot AR.Drone 2.0
|
||||
*
|
||||
* Sensors from vertical camera and IMU of Parrot AR.Drone 2.0
|
||||
*/
|
||||
|
||||
#ifndef OPTICFLOW_MODULE_H
|
||||
#define OPTICFLOW_MODULE_H
|
||||
|
||||
#include "std.h"
|
||||
|
||||
// Module functions
|
||||
extern void opticflow_module_init(void);
|
||||
extern void opticflow_module_run(void);
|
||||
extern void opticflow_module_start(void);
|
||||
extern void opticflow_module_stop(void);
|
||||
|
||||
#endif /* OPTICFLOW_MODULE_H */
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2015
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/ctrl/ctrl_module_demo.h
|
||||
* @brief example empty controller
|
||||
*
|
||||
*/
|
||||
|
||||
#include "modules/ctrl/ctrl_module_demo.h"
|
||||
#include "state.h"
|
||||
#include "subsystems/radio_control.h"
|
||||
#include "firmwares/rotorcraft/stabilization.h"
|
||||
|
||||
struct ctrl_module_demo_struct {
|
||||
int rc_x;
|
||||
int rc_y;
|
||||
int rc_z;
|
||||
int rc_t;
|
||||
|
||||
} ctrl_module_demo;
|
||||
|
||||
float ctrl_module_demo_pr_ff_gain = 0.2f; // Pitch/Roll
|
||||
float ctrl_module_demo_pr_d_gain = 0.1f;
|
||||
float ctrl_module_demo_y_ff_gain = 0.4f; // Yaw
|
||||
float ctrl_module_demo_y_d_gain = 0.05f;
|
||||
|
||||
void ctrl_module_init(void);
|
||||
void ctrl_module_run(bool_t in_flight);
|
||||
|
||||
void ctrl_module_init(void)
|
||||
{
|
||||
ctrl_module_demo.rc_x = 0;
|
||||
ctrl_module_demo.rc_y = 0;
|
||||
ctrl_module_demo.rc_z = 0;
|
||||
ctrl_module_demo.rc_t = 0;
|
||||
}
|
||||
|
||||
// Old-fashened rate control without reference model nor attitude
|
||||
void ctrl_module_run(bool_t in_flight)
|
||||
{
|
||||
if (!in_flight) {
|
||||
// Reset integrators
|
||||
stabilization_cmd[COMMAND_ROLL] = 0;
|
||||
stabilization_cmd[COMMAND_PITCH] = 0;
|
||||
stabilization_cmd[COMMAND_YAW] = 0;
|
||||
stabilization_cmd[COMMAND_THRUST] = 0;
|
||||
} else {
|
||||
stabilization_cmd[COMMAND_ROLL] = ctrl_module_demo.rc_x * ctrl_module_demo_pr_ff_gain - stateGetBodyRates_i()->p *
|
||||
ctrl_module_demo_pr_d_gain;
|
||||
stabilization_cmd[COMMAND_PITCH] = ctrl_module_demo.rc_y * ctrl_module_demo_pr_ff_gain - stateGetBodyRates_i()->q *
|
||||
ctrl_module_demo_pr_d_gain;
|
||||
stabilization_cmd[COMMAND_YAW] = ctrl_module_demo.rc_z * ctrl_module_demo_y_ff_gain - stateGetBodyRates_i()->r *
|
||||
ctrl_module_demo_y_d_gain;
|
||||
stabilization_cmd[COMMAND_THRUST] = ctrl_module_demo.rc_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Call our controller
|
||||
// Implement own Horizontal loops
|
||||
void guidance_h_module_enter(void)
|
||||
{
|
||||
ctrl_module_init();
|
||||
}
|
||||
void guidance_h_module_read_rc(void)
|
||||
{
|
||||
// -MAX_PPRZ to MAX_PPRZ
|
||||
ctrl_module_demo.rc_t = radio_control.values[RADIO_THROTTLE];
|
||||
ctrl_module_demo.rc_x = radio_control.values[RADIO_ROLL];
|
||||
ctrl_module_demo.rc_y = radio_control.values[RADIO_PITCH];
|
||||
ctrl_module_demo.rc_z = radio_control.values[RADIO_YAW];
|
||||
}
|
||||
|
||||
void guidance_h_module_run(bool_t in_flight)
|
||||
{
|
||||
// Call full inner-/outerloop / horizontal-/vertical controller:
|
||||
ctrl_module_run(in_flight);
|
||||
}
|
||||
|
||||
// Implement own Horizontal loops
|
||||
inline void guidance_v_module_enter(void) {}
|
||||
inline void guidance_v_module_run(UNUSED bool_t in_flight) {}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2015
|
||||
*
|
||||
* This file is part of Paparazzi.
|
||||
*
|
||||
* Paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* Paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modules/ctrl/ctrl_module_demo.c
|
||||
* @brief example empty controller
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CTRL_MODULE_DEMO_H_
|
||||
#define CTRL_MODULE_DEMO_H_
|
||||
|
||||
#include <std.h>
|
||||
|
||||
// Settings
|
||||
extern float ctrl_module_demo_pr_ff_gain; // Pitch/Roll
|
||||
extern float ctrl_module_demo_pr_d_gain;
|
||||
extern float ctrl_module_demo_y_ff_gain; // Yaw
|
||||
extern float ctrl_module_demo_y_d_gain;
|
||||
|
||||
|
||||
// Demo with own guidance_h
|
||||
#define GUIDANCE_H_MODE_MODULE_SETTING GUIDANCE_H_MODE_MODULE
|
||||
|
||||
// and own guidance_v
|
||||
#define GUIDANCE_V_MODE_MODULE_SETTING GUIDANCE_V_MODE_MODULE
|
||||
|
||||
// Implement own Horizontal loops
|
||||
extern void guidance_h_module_enter(void);
|
||||
extern void guidance_h_module_read_rc(void);
|
||||
extern void guidance_h_module_run(bool_t in_flight);
|
||||
|
||||
// Implement own Horizontal loops
|
||||
extern void guidance_v_module_enter(void);
|
||||
extern void guidance_v_module_run(bool_t in_flight);
|
||||
|
||||
|
||||
#endif /* HOVER_STABILIZATION_H_ */
|
||||
@@ -1266,7 +1266,7 @@ let listen_flight_params = fun geomap auto_center_new_ac alert alt_graph ->
|
||||
let color =
|
||||
match ap_mode with
|
||||
"AUTO2" | "NAV" -> ok_color
|
||||
| "AUTO1" | "R_RCC" | "A_RCC" | "ATT_C" | "R_ZH" | "A_ZH" | "HOVER" | "HOV_C" | "H_ZH" -> "#10F0E0"
|
||||
| "AUTO1" | "R_RCC" | "A_RCC" | "ATT_C" | "R_ZH" | "A_ZH" | "HOVER" | "HOV_C" | "H_ZH" | "MODULE" -> "#10F0E0"
|
||||
| "MANUAL" | "RATE" | "ATT" | "RC_D" | "CF" | "FWD" -> warning_color
|
||||
| _ -> alert_color in
|
||||
ac.strip#set_color "AP" color;
|
||||
|
||||
@@ -4,7 +4,7 @@ let hostname = ref "localhost"
|
||||
|
||||
(** FIXME: Should be read from messages.xml *)
|
||||
let fixedwing_ap_modes = [|"MANUAL";"AUTO1";"AUTO2";"HOME";"NOGPS";"FAIL"|]
|
||||
let rotorcraft_ap_modes = [|"KILL";"SAFE";"HOME";"RATE";"ATT";"R_RCC";"A_RCC";"ATT_C";"R_ZH";"A_ZH";"HOVER";"HOV_C";"H_ZH";"NAV";"RC_D";"CF";"FWD"|]
|
||||
let rotorcraft_ap_modes = [|"KILL";"SAFE";"HOME";"RATE";"ATT";"R_RCC";"A_RCC";"ATT_C";"R_ZH";"A_ZH";"HOVER";"HOV_C";"H_ZH";"NAV";"RC_D";"CF";"FWD";"MODULE"|]
|
||||
let _AUTO2 = 2
|
||||
let gaz_modes = [|"MANUAL";"THROTTLE";"CLIMB";"ALT"|]
|
||||
let lat_modes = [|"MANUAL";"ROLL_RATE";"ROLL";"COURSE"|]
|
||||
|
||||
Reference in New Issue
Block a user