Migration to OpenModelica 1.25 and FMUs Generation
This commit is contained in:
BIN
CoSimulation/FMUs_OpenModelica_1.25/ControlDroneNavigation.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/ControlDroneNavigation.fmu
Normal file
Binary file not shown.
Binary file not shown.
BIN
CoSimulation/FMUs_OpenModelica_1.25/QuadcopterModel.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/QuadcopterModel.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_OpenModelica_1.25/RemoteControl.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/RemoteControl.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_OpenModelica_1.25/StabilityRequirement.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/StabilityRequirement.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_OpenModelica_1.25/Wind2DModel.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/Wind2DModel.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_OpenModelica_1.25/WindProfile.fmu
Normal file
BIN
CoSimulation/FMUs_OpenModelica_1.25/WindProfile.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_SimulationX/AIDA_Drone_FMU.fmu
Normal file
BIN
CoSimulation/FMUs_SimulationX/AIDA_Drone_FMU.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/FMUs_SimulationX/Environment.fmu
Normal file
BIN
CoSimulation/FMUs_SimulationX/Environment.fmu
Normal file
Binary file not shown.
6002
CoSimulation/FMUs_SimulationX/RunFlightPlan.csv
Normal file
6002
CoSimulation/FMUs_SimulationX/RunFlightPlan.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
CoSimulation/FMUs_SimulationX/RunFlightPlan.fmu
Normal file
BIN
CoSimulation/FMUs_SimulationX/RunFlightPlan.fmu
Normal file
Binary file not shown.
BIN
CoSimulation/Tutorial_PyCharm_PyFMI_Setup.docx
Normal file
BIN
CoSimulation/Tutorial_PyCharm_PyFMI_Setup.docx
Normal file
Binary file not shown.
180
CoSimulation/simulate_aida_coupled_FMUSimX.py
Normal file
180
CoSimulation/simulate_aida_coupled_FMUSimX.py
Normal file
@@ -0,0 +1,180 @@
|
||||
"""
|
||||
simulate_aida_coupled_interactive.py
|
||||
Interactive co-simulation of the AIDA Drone and Environment FMUs
|
||||
Choose at runtime between RunFlightPlan FMU or CSV-based flight plan.
|
||||
"""
|
||||
|
||||
from pyfmi import load_fmu
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
|
||||
# -----------------------------
|
||||
# 1. Ask the user
|
||||
# -----------------------------
|
||||
choice = input("Use CSV flight plan instead of RunFlightPlan FMU? (y/n): ").strip().lower()
|
||||
USE_CSV = choice == 'y'
|
||||
|
||||
# -----------------------------
|
||||
# 2. Paths
|
||||
# -----------------------------
|
||||
FMU_PATH = r".\FMUs_SimulationX"
|
||||
|
||||
fmu_drone = os.path.join(FMU_PATH, "AIDA_Drone_FMU.fmu")
|
||||
fmu_env = os.path.join(FMU_PATH, "Environment.fmu")
|
||||
fmu_plan = os.path.join(FMU_PATH, "RunFlightPlan.fmu")
|
||||
flight_plan_csv = os.path.join(FMU_PATH, "RunFlightPlan.csv")
|
||||
|
||||
# -----------------------------
|
||||
# 3. Load FMUs
|
||||
# -----------------------------
|
||||
print("Loading FMUs...")
|
||||
drone = load_fmu(fmu_drone)
|
||||
env = load_fmu(fmu_env)
|
||||
print("Drone and Environment FMUs loaded.")
|
||||
|
||||
if USE_CSV:
|
||||
print("Using CSV-based flight plan...")
|
||||
|
||||
# Load CSV
|
||||
plan_df = pd.read_csv(flight_plan_csv)
|
||||
|
||||
# Optional: reset index after filtering
|
||||
plan_df = plan_df.reset_index(drop=True)
|
||||
|
||||
# Extract time and consign values
|
||||
time_points = plan_df['Time'].values
|
||||
x_consign = plan_df['runFlightPlan1_Drone_Position_Consign_1'].values
|
||||
y_consign = plan_df['runFlightPlan1_Drone_Position_Consign_2'].values
|
||||
z_consign = plan_df['runFlightPlan1_Drone_Position_Consign_3'].values
|
||||
|
||||
else:
|
||||
print("Using RunFlightPlan FMU...")
|
||||
plan = load_fmu(fmu_plan)
|
||||
time_points = np.arange(0.0, 250.0, 0.002)
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 4. Initialize FMUs
|
||||
# -----------------------------
|
||||
start_time = float(time_points[0])
|
||||
stop_time = float(time_points[-1])
|
||||
step_size = np.mean(np.diff(time_points))
|
||||
|
||||
drone.initialize(start_time, stop_time)
|
||||
env.initialize(start_time, stop_time)
|
||||
if not USE_CSV:
|
||||
plan.initialize(time_points[0], time_points[-1])
|
||||
|
||||
pos_x, pos_y, pos_z = [], [], []
|
||||
|
||||
print("Starting co-simulation...")
|
||||
|
||||
# -----------------------------
|
||||
# 5. Simulation loop
|
||||
# -----------------------------
|
||||
for i, t in enumerate(time_points):
|
||||
# 1. Get position consigns
|
||||
if USE_CSV:
|
||||
pos_consign = [x_consign[i], y_consign[i], z_consign[i]]
|
||||
else:
|
||||
pos_consign = plan.get([
|
||||
"runFlightPlan1.Drone_Position_Consign[1]",
|
||||
"runFlightPlan1.Drone_Position_Consign[2]",
|
||||
"runFlightPlan1.Drone_Position_Consign[3]",
|
||||
])
|
||||
|
||||
# 2. Send consigns to drone
|
||||
drone.set([
|
||||
"controlPosition1.Drone_position_consign[1]",
|
||||
"controlPosition1.Drone_position_consign[2]",
|
||||
"controlPosition1.Drone_position_consign[3]"
|
||||
], pos_consign)
|
||||
|
||||
# 3. Get feedback from environment
|
||||
pos_feedback = env.get([
|
||||
"generatePositioningSignal1.Positioning_signal[1]",
|
||||
"generatePositioningSignal1.Positioning_signal[2]",
|
||||
"generatePositioningSignal1.Positioning_signal[3]",
|
||||
"generatePositioningSignal1.Positioning_signal[4]"
|
||||
])
|
||||
|
||||
# 4. Send feedback to drone
|
||||
drone.set([
|
||||
"acquirePositioningSignal1.Positioning_signal[1]",
|
||||
"acquirePositioningSignal1.Positioning_signal[2]",
|
||||
"acquirePositioningSignal1.Positioning_signal[3]",
|
||||
"acquirePositioningSignal1.Positioning_signal[4]"
|
||||
], pos_feedback)
|
||||
|
||||
# 5. Step simulation
|
||||
drone.do_step(current_t=t, step_size=step_size, new_step=True)
|
||||
try:
|
||||
pos_cmd = drone.get([
|
||||
"controlPosition1.Position_command[1]",
|
||||
"controlPosition1.Position_command[2]",
|
||||
"controlPosition1.Position_command[3]"
|
||||
])
|
||||
except Exception as e:
|
||||
if USE_CSV:
|
||||
if i == 0:
|
||||
print(f"Warning: could not read drone outputs at t={t:.2f}s (likely not initialized yet).")
|
||||
# Use fallback zero values until valid output exists
|
||||
pos_cmd = [0.0, 0.0, 0.0]
|
||||
else:
|
||||
raise # Re-raise the error if it's unexpected in FMU mode
|
||||
|
||||
env.set([
|
||||
"trajectoryManagement1.Position_Command[1]",
|
||||
"trajectoryManagement1.Position_Command[2]",
|
||||
"trajectoryManagement1.Position_Command[3]"
|
||||
], pos_cmd)
|
||||
env.do_step(current_t=t, step_size=step_size, new_step=True)
|
||||
|
||||
if not USE_CSV:
|
||||
plan.do_step(current_t=t, step_size=step_size, new_step=True)
|
||||
|
||||
# 6. Store results
|
||||
pos_x.append(pos_cmd[0])
|
||||
pos_y.append(pos_cmd[1])
|
||||
pos_z.append(pos_cmd[2])
|
||||
|
||||
print("Simulation finished.")
|
||||
|
||||
# -----------------------------
|
||||
# 6. Terminate FMUs
|
||||
# -----------------------------
|
||||
drone.terminate()
|
||||
env.terminate()
|
||||
if not USE_CSV:
|
||||
plan.terminate()
|
||||
|
||||
# -----------------------------
|
||||
# 7. Plot results
|
||||
# -----------------------------
|
||||
plt.figure(figsize=(12, 5))
|
||||
|
||||
# Time evolution
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.plot(time_points, pos_x, label="X command")
|
||||
plt.plot(time_points, pos_y, label="Y command")
|
||||
plt.plot(time_points, pos_z, label="Z command")
|
||||
plt.xlabel("Time (s)")
|
||||
plt.ylabel("Position command")
|
||||
plt.title("Position commands over time")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
|
||||
# 2D trajectory
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.plot(pos_y, pos_z, linewidth=2, color='tab:blue')
|
||||
plt.xlabel("X position command")
|
||||
plt.ylabel("Y position command")
|
||||
plt.title("Drone 2D Trajectory (Y vs X)")
|
||||
plt.axis('equal')
|
||||
plt.grid(True)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
158
CoSimulation/simulate_aida_coupled_FMUs_OM125.py
Normal file
158
CoSimulation/simulate_aida_coupled_FMUs_OM125.py
Normal file
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
simulate_aida_coupled_interactive.py
|
||||
Interactive co-simulation of the AIDA Drone and Environment FMUs
|
||||
Choose at runtime between RunFlightPlan FMU or CSV-based flight plan.
|
||||
"""
|
||||
|
||||
from pyfmi import load_fmu
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 2. Paths
|
||||
# -----------------------------
|
||||
FMU_PATH = r".\FMUs_OpenModelica_1.25"
|
||||
|
||||
fmu_drone = os.path.join(FMU_PATH, "QuadcopterModel.fmu")
|
||||
fmu_wind = os.path.join(FMU_PATH, "WindProfile.fmu")
|
||||
fmu_remote = os.path.join(FMU_PATH, "RemoteControl.fmu")
|
||||
fmu_control_navigation = os.path.join(FMU_PATH, "ControlDroneNavigation.fmu")
|
||||
fmu_LowLevelFlightControlSystem = os.path.join(FMU_PATH, "LowLevelFlightControlSystem.fmu")
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 3. Load FMUs
|
||||
# -----------------------------
|
||||
print("Loading FMUs...")
|
||||
drone = load_fmu(fmu_drone)
|
||||
wind = load_fmu(fmu_wind)
|
||||
remote = load_fmu(fmu_remote)
|
||||
control_navigation = load_fmu(fmu_control_navigation)
|
||||
low_level_fcs = load_fmu(fmu_LowLevelFlightControlSystem)
|
||||
print("All system FMUs loaded.")
|
||||
|
||||
FMUS = {
|
||||
"drone": drone,
|
||||
"wind": wind,
|
||||
"remote": remote,
|
||||
"control_navigation": control_navigation,
|
||||
"low_level_fcs": low_level_fcs,
|
||||
}
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 4. Initialize FMUs
|
||||
# -----------------------------
|
||||
start_time = float(0)
|
||||
stop_time = float(250)
|
||||
step_size = 0.1
|
||||
|
||||
drone.initialize(start_time, stop_time)
|
||||
wind.initialize(start_time, stop_time)
|
||||
remote.initialize(start_time, stop_time)
|
||||
control_navigation.initialize(start_time, stop_time)
|
||||
low_level_fcs.initialize(start_time, stop_time)
|
||||
|
||||
time_points = np.arange(start_time, stop_time + 0.5 * step_size, step_size)
|
||||
|
||||
def safe_get(fmu, names, default=None):
|
||||
if isinstance(names, str):
|
||||
names = [names]
|
||||
try:
|
||||
vals = fmu.get(names)
|
||||
return vals
|
||||
except Exception as e:
|
||||
print(f"[WARN] get from {fmu.get_name()} failed for {names}: {e}")
|
||||
if default is None:
|
||||
return [0.0] * len(names)
|
||||
return default
|
||||
|
||||
def safe_set(fmu, names, values):
|
||||
if isinstance(names, str):
|
||||
names = [names]
|
||||
values = [values]
|
||||
try:
|
||||
fmu.set(names, values)
|
||||
except Exception as e:
|
||||
print(f"[WARN] set on {fmu.get_name()} failed for {names}: {e}")
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 5. Initial values (t = 0)
|
||||
# -----------------------------
|
||||
wind_Fx, wind_Fy = safe_get(wind, ["Fx", "Fy"], default=[0.0, 0.0])
|
||||
|
||||
# Quadcopter states
|
||||
# Assuming exported as Position[1..3], Speed[1..3], Attitude[1..3], AngularVelocities[1..3]
|
||||
quad_pos = safe_get(drone, ["Position[1]", "Position[2]", "Position[3]"], default=[0.0, 0.0, 0.0])
|
||||
quad_speed = safe_get(drone, ["Speed[1]", "Speed[2]", "Speed[3]"], default=[0.0, 0.0, 0.0])
|
||||
quad_att = safe_get(drone, ["Attitude[1]", "Attitude[2]", "Attitude[3]"], default=[0.0, 0.0, 0.0])
|
||||
quad_ang = safe_get(drone, ["AngularVelocities[1]", "AngularVelocities[2]", "AngularVelocities[3]"],
|
||||
default=[0.0, 0.0, 0.0])
|
||||
|
||||
# Remote control commands
|
||||
rc_names = ["RollCommand", "PitchCommand", "VerticalSpeedCommand",
|
||||
"YawCommand", "ControlMode", "IndicatorYawConsign"]
|
||||
rc_vals = safe_get(remote, rc_names, default=[0.0] * len(rc_names))
|
||||
(rc_roll, rc_pitch, rc_vspeed, rc_yaw, rc_mode, rc_ind_yaw) = rc_vals
|
||||
|
||||
# Navigation consigns
|
||||
nav_pos_consign = safe_get(control_navigation,
|
||||
["DronPositionConsign[1]", "DronPositionConsign[2]", "DronPositionConsign[3]"],
|
||||
default=[0.0, 0.0, 0.0],
|
||||
)
|
||||
nav_yaw_consign = safe_get(control_navigation, ["YawConsign"], default=[0.0])[0]
|
||||
nav_selected_mode = safe_get(control_navigation, ["SelectedControlMode"], default=[0.0])[0]
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 6. Logging buffers
|
||||
# -----------------------------
|
||||
times = []
|
||||
pos_x = []
|
||||
pos_y = []
|
||||
pos_z = []
|
||||
yaw_log = []
|
||||
|
||||
# -----------------------------
|
||||
# 7. Simulation loop
|
||||
# -----------------------------
|
||||
print("Starting co-simulation...")
|
||||
current_time = start_time
|
||||
|
||||
for i, t in enumerate(time_points):
|
||||
# 7.1 Step RemoteControl
|
||||
remote.do_step(current_t=current_time, step_size=step_size, new_step=True)
|
||||
rc_vals = safe_get(remote, rc_names, default=rc_vals)
|
||||
(rc_roll, rc_pitch, rc_vspeed, rc_yaw, rc_mode, rc_ind_yaw) = rc_vals
|
||||
|
||||
# 8.2 Feed RemoteControl -> ControlDroneNavigation
|
||||
# connect(remoteControl1.ControlMode, controlDroneNavigation1.APEngagement)
|
||||
# connect(remoteControl1.IndicatorYawConsign, controlDroneNavigation1.IndicatorYawConsign)
|
||||
safe_set(control_navigation,
|
||||
["APEngagement", "IndicatorYawConsign"],
|
||||
[rc_mode, rc_ind_yaw])
|
||||
|
||||
# Quadcopter yaw feedback to navigation (connect(controlDroneNavigation1.Yaw, quadcopterModel1.Attitude[3]))
|
||||
yaw_feedback = quad_att[2] # Attitude[3]
|
||||
control_navigation.set("Yaw", yaw_feedback)
|
||||
|
||||
# 8.3 Step ControlDroneNavigation
|
||||
control_navigation.do_step(current_t=current_time, step_size=step_size, new_step=True)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# 8. Terminate FMUs
|
||||
# -----------------------------
|
||||
drone.terminate()
|
||||
control_navigation.terminate()
|
||||
low_level_fcs.terminate()
|
||||
remote.terminate()
|
||||
wind.terminate()
|
||||
|
||||
# -----------------------------
|
||||
# 9. Plot results
|
||||
# -----------------------------
|
||||
6
CoSimulation/test_pyfmi.py
Normal file
6
CoSimulation/test_pyfmi.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# test_pyfmi.py
|
||||
from pyfmi.examples import fmi_bouncing_ball_cs
|
||||
|
||||
print("Testing PyFMI installation...")
|
||||
fmi_bouncing_ball_cs.run_demo()
|
||||
print("✅ PyFMI and FMI Library work correctly!")
|
||||
@@ -1,91 +0,0 @@
|
||||
model AIDA_System "AIDAModel-integrationProSivic_reference.isx"
|
||||
AIDAModelica.QuadcopterModel quadcopterModel1(
|
||||
rigidBodyKinematicModel1(
|
||||
computeDronePosition1(
|
||||
integrator10(initType = Modelica.Blocks.Types.Init.SteadyState, y_start = -0.29),
|
||||
integrator11(initType = Modelica.Blocks.Types.Init.InitialOutput),
|
||||
integrator12(initType = Modelica.Blocks.Types.Init.InitialOutput))),
|
||||
rigidBodyDynamicModel1(
|
||||
computeDroneVelocity1(
|
||||
integrator4(initType = Modelica.Blocks.Types.Init.SteadyState)))) annotation(
|
||||
Placement(visible = true, transformation(extent = {{29, -8}, {49, 17}}, rotation = 0)));
|
||||
|
||||
AIDAModelica.LowLevelFlightControlSystem lowLevelFlightControlSystem1(
|
||||
controlAltitude1(computeAltitudeConsign1(
|
||||
PID1(k = 30, Ti = 1, Td = 0.1, Nd = 10, initType=Modelica.Blocks.Types.InitPID.InitialOutput)),
|
||||
pID_2(k = 25, Ti = 0.5, Td = 0.08, initType=Modelica.Blocks.Types.InitPID.InitialOutput)),
|
||||
attitudeControl1(Test_CstMomentumActiv = false, Test_open_loop = {false, false, false},
|
||||
controlRollAngle1(xAngularSpeedErrorModel1(Kwphi = 1.5),
|
||||
PID(k = 0.07, Ti = 30, Td = 0.02, Nd = 0.1,initType=Modelica.Blocks.Types.InitPID.InitialOutput,
|
||||
Add(k1 = 1, k2 = 1, k3 = 1))),
|
||||
controlPitchAngle1(yAngularSpeedErrorModel1(Kwteta = 1.5, RTStepConsign = false),
|
||||
PID1(k = 0.07, Ti = 30, Td = 0.02, Nd = 0.1,initType=Modelica.Blocks.Types.InitPID.InitialOutput,
|
||||
Add(k1 = 1, k2 = 1, k3 = 1))),
|
||||
controlYawAngle1(zAngularSpeedErrorModel1(Kwyaw = 2),
|
||||
PID2(k = 0.04, Ti = 20, Td = 0.5, Nd = 2.5,initType=Modelica.Blocks.Types.InitPID.InitialOutput,
|
||||
Add(k1 = 1, k2 = 1, k3 = 1)))),
|
||||
|
||||
positionControl1(
|
||||
controlSpeed1(
|
||||
PID(k = 0.8, Ti = 1,initType=Modelica.Blocks.Types.InitPID.InitialOutput),
|
||||
PID2(k = 0.8, Ti = 1,initType=Modelica.Blocks.Types.InitPID.InitialOutput),
|
||||
PID1(k = 30, Ti = 1, Td=0.1,initType=Modelica.Blocks.Types.InitPID.InitialOutput)))) annotation(
|
||||
Placement(visible = true, transformation(extent = {{-37, -6}, {-12, 19}}, rotation = 0)));
|
||||
AIDAModelica.ControlDroneNavigation controlDroneNavigation1 annotation(
|
||||
Placement(visible = true, transformation(extent = {{-79, -3}, {-59, 17}}, rotation = 0)));
|
||||
AIDAModelica.RemoteControl remoteControl1(
|
||||
VS_cmd=-0.5,
|
||||
VS_cmd_t={0.1,5},
|
||||
Pitch_cmd=0.02,
|
||||
Pitch_cmd_t={6,12},
|
||||
Yaw_cmd_t={15,19},
|
||||
Roll_cmd=0.02,
|
||||
Roll_cmd_t={3,9},
|
||||
Auto_Ctl_t=0.2) annotation(
|
||||
Placement(visible = true, transformation(extent = {{-57, 49}, {-32, 69}}, rotation = 0)));
|
||||
equation
|
||||
connect(lowLevelFlightControlSystem1.AngularSpeed, quadcopterModel1.AngularVelocities) annotation(
|
||||
Line(points = {{-33, -6}, {-33, -30}, {81.1667, -30}, {81.1667, 12}, {49.1667, 12}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.Attitude, quadcopterModel1.Attitude) annotation(
|
||||
Line(points = {{-29, -6}, {-29, -26}, {69.3333, -26}, {69.3333, 8}, {49.3333, 8}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.Position, quadcopterModel1.Position) annotation(
|
||||
Line(points = {{-24.5, -6}, {-24.5, -22}, {61.5, -22}, {61.5, 4}, {49.5, 4}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.Speed, quadcopterModel1.Speed) annotation(
|
||||
Line(points = {{-21, -6}, {-17.6667, -6}, {-17.6667, -18}, {57.3333, -18}, {57.3333, 0}, {49.3333, 0}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.Accelerations, quadcopterModel1.Accelerations) annotation(
|
||||
Line(points = {{-17, -6}, {-13.8333, -6}, {-13.8333, -16.0333}, {54.9167, -16.0333}, {54.9167, -4.0333}, {48.4167, -4.0333}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.ThrottleCommand1, lowLevelFlightControlSystem1.ThrottleCommand1) annotation(
|
||||
Line(points = {{29, 10.75}, {1, 10.75}, {1, 14}, {-12, 14}}, color = {0, 0, 127}, thickness = 0.015625));
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand2, quadcopterModel1.ThrottleCommand2) annotation(
|
||||
Line(points = {{-12, 9}, {8.5, 9}, {8.5, 7}, {29, 7}}, color = {0, 0, 127}, thickness = 0.015625));
|
||||
connect(quadcopterModel1.ThrottleCommand3, lowLevelFlightControlSystem1.ThrottleCommand3) annotation(
|
||||
Line(points = {{29, 2.41667}, {12.5, 2.41667}, {12.5, 4}, {-12, 4}}, color = {0, 0, 127}, thickness = 0.015625));
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand4, quadcopterModel1.ThrottleCommand4) annotation(
|
||||
Line(points = {{-12, -1}, {26, -1}, {26, -2}, {29, -2}}, color = {0, 0, 127}, thickness = 0.015625));
|
||||
connect(quadcopterModel1.Speed[:], lowLevelFlightControlSystem1.Speed[:]) annotation(
|
||||
Line);
|
||||
connect(controlDroneNavigation1.YawConsign, lowLevelFlightControlSystem1.YawConsign) annotation(
|
||||
Line(points = {{-59, 7}, {-34, 7}, {-34, 4}, {-37, 4}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(controlDroneNavigation1.DronPositionConsign[:], lowLevelFlightControlSystem1.DronePositionConsign[:]) annotation(
|
||||
Line(points = {{-59, 12}, {-48, 12}, {-48, 14}, {-37, 14}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(lowLevelFlightControlSystem1.SelectedControlMode, controlDroneNavigation1.SelectedControlMode) annotation(
|
||||
Line(points = {{-37, -1}, {-54, -1}, {-54, 2}, {-59, 2}}, color = {255, 0, 255}, thickness = 0.0625));
|
||||
connect(lowLevelFlightControlSystem1.RCVerticalSpeedCommand, remoteControl1.VerticalSpeedCommand) annotation(
|
||||
Line(points = {{-31, 19}, {-52.75, 19}, {-52.75, 49}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.RCYawCommand, remoteControl1.YawCommand) annotation(
|
||||
Line(points = {{-22, 19}, {-36.4167, 19}, {-36.4167, 51}, {-35.4167, 51}, {-35.4167, 49}, {-36.4167, 49}}, color = {0, 0, 127}));
|
||||
connect(remoteControl1.RollCommand, lowLevelFlightControlSystem1.RCAttitudeCommands[1]) annotation(
|
||||
Line(points = {{-47, 49}, {-47, 22}, {-27, 22}, {-27, 19}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(remoteControl1.PitchCommand, lowLevelFlightControlSystem1.RCAttitudeCommands[2]) annotation(
|
||||
Line(points = {{-42, 49}, {-42, 22}, {-27, 22}, {-27, 19}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(remoteControl1.IndicatorYawConsign, controlDroneNavigation1.IndicatorYawConsign) annotation(
|
||||
Line(points = {{-57, 59}, {-94, 59}, {-94, 6}, {-80, 6}, {-80, 8}, {-78, 8}, {-78, 8}, {-78, 8}}, color = {255, 0, 255}));
|
||||
connect(remoteControl1.ControlMode, controlDroneNavigation1.APEngagement) annotation(
|
||||
Line(points = {{-57, 54}, {-84, 54}, {-84, 12}, {-79, 12}}, color = {255, 0, 255}, thickness = 0.015625));
|
||||
connect(controlDroneNavigation1.Yaw, quadcopterModel1.Attitude[3]) annotation(
|
||||
Line(points = {{-79, 2}, {-87, 2}, {-87, -36}, {91, -36}, {91, 8}, {49, 8}, {49, 8}, {49, 8}, {49, 8}}, color = {0, 0, 127}));
|
||||
annotation(
|
||||
Icon(coordinateSystem(grid = {3, 2})),
|
||||
experiment(StartTime = 0, StopTime = 30, Tolerance = 1e-06, Interval = 0.002),
|
||||
__OpenModelica_simulationFlags(jacobian = "coloredNumerical", s = "dassl", lv = "LOG_STATS"));
|
||||
end AIDA_System;
|
||||
@@ -1,215 +0,0 @@
|
||||
within AIDAModelica;
|
||||
// CP: 65001
|
||||
// SimulationX Version: 3.8.2.45319 x64
|
||||
|
||||
model RemoteControl "RemoteControl"
|
||||
Real VerticalSpeedCommand_i(start=0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput VerticalSpeedCommand(
|
||||
quantity="Mechanics.Translation.Velocity",
|
||||
displayUnit="m/s") "'output Real' as connector" annotation(Placement(
|
||||
transformation(extent={{12,28},{32,48}}),
|
||||
iconTransformation(
|
||||
origin={-75,-100},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=-90)));
|
||||
Real RollCommand_i(start=0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput RollCommand(
|
||||
quantity="Mechanics.Rotation.Angle",
|
||||
displayUnit="rad") "'output Real' as connector" annotation(Placement(
|
||||
transformation(extent={{56,8},{76,28}}),
|
||||
iconTransformation(
|
||||
origin={-25,-100},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=-90)));
|
||||
Real PitchCommand_i(start=0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput PitchCommand(
|
||||
quantity="Mechanics.Rotation.Angle",
|
||||
displayUnit="rad") "'output Real' as connector" annotation(Placement(
|
||||
transformation(extent={{-38,-46},{-18,-26}}),
|
||||
iconTransformation(
|
||||
origin={25,-100},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=-90)));
|
||||
Real YawCommand_i(start=0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput YawCommand(
|
||||
quantity="Mechanics.Rotation.Angle",
|
||||
displayUnit="rad") "'output Real' as connector" annotation(Placement(
|
||||
transformation(extent={{18,-52},{38,-32}}),
|
||||
iconTransformation(
|
||||
origin={75,-100},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=-90)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput ControlMode "'output Boolean' as connector" annotation(Placement(
|
||||
transformation(extent={{-10,-10},{10,10}}),
|
||||
iconTransformation(
|
||||
origin={-125,-50},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=180)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput IndicatorYawConsign "'output Boolean' as connector" annotation(Placement(
|
||||
transformation(
|
||||
origin={-45,45},
|
||||
extent={{-17,-17},{17,17}}),
|
||||
iconTransformation(
|
||||
origin={-125,0},
|
||||
extent={{-10,-10},{10,10}},
|
||||
rotation=-180)));
|
||||
parameter Real VS_cmd=0.5;
|
||||
parameter Real[2] VS_cmd_t={3, 5} "Instants de démarrage et fin du step";
|
||||
parameter Real Pitch_cmd=0.03;
|
||||
parameter Real[2] Pitch_cmd_t={1, 4} "Instants de démarrage et fin du step, après stabilisation verticale";
|
||||
parameter Real Yaw_cmd=0.5;
|
||||
parameter Real[2] Yaw_cmd_t={6, 8} "Instants de démarrage et fin du step";
|
||||
parameter Real Roll_cmd=0.2 "Amplitude step ";
|
||||
parameter Real Roll_cmd_t[2]={1, 100} "Instants de démarrage et fin du step";
|
||||
parameter Real Tcst=0.1 "constante de temps pour filter les sorties du remote ctl";
|
||||
Boolean Auto_Ctl_Enabled(start=true);
|
||||
parameter Real Auto_Ctl_t=0.1 "Instant de déclenchement du mode auto";
|
||||
initial equation
|
||||
PitchCommand = 0;
|
||||
RollCommand = 0;
|
||||
YawCommand = 0;
|
||||
VerticalSpeedCommand = 0;
|
||||
PitchCommand_i = 0;
|
||||
RollCommand_i = 0;
|
||||
YawCommand_i = 0;
|
||||
VerticalSpeedCommand_i = 0;
|
||||
ControlMode = false;
|
||||
IndicatorYawConsign = false;
|
||||
Auto_Ctl_Enabled=true;
|
||||
algorithm
|
||||
|
||||
when time > Auto_Ctl_t and Auto_Ctl_Enabled==true then
|
||||
ControlMode:=true;
|
||||
end when;
|
||||
|
||||
when time > VS_cmd_t[1] then
|
||||
VerticalSpeedCommand_i := VS_cmd;
|
||||
ControlMode:=false;
|
||||
Auto_Ctl_Enabled:=false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] then
|
||||
VerticalSpeedCommand_i := 0;
|
||||
end when;
|
||||
when time > VS_cmd_t[2]+ Pitch_cmd_t[1] then
|
||||
PitchCommand_i := Pitch_cmd;
|
||||
ControlMode:=false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2]+ Pitch_cmd_t[2] then
|
||||
PitchCommand_i := 0;
|
||||
end when;
|
||||
when time > VS_cmd_t[2]+ Roll_cmd_t[1] then
|
||||
RollCommand_i := Roll_cmd;
|
||||
ControlMode:=false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2]+ Roll_cmd_t[2] then
|
||||
RollCommand_i := 0;
|
||||
end when;
|
||||
//Yaw command
|
||||
when time > VS_cmd_t[2]+ Yaw_cmd_t[1] then
|
||||
YawCommand_i := Yaw_cmd;
|
||||
ControlMode:=false;
|
||||
IndicatorYawConsign:=true;
|
||||
end when;
|
||||
//IndicatorYawConsign := true;
|
||||
when time > VS_cmd_t[2]+ Yaw_cmd_t[2] then
|
||||
YawCommand_i := 0;
|
||||
end when;
|
||||
//IndicatorYawConsign := false;
|
||||
/*if time>Yaw_cmd_t[2] then
|
||||
|
||||
int_yaw := 0;
|
||||
IndicatorYawConsign := false;
|
||||
|
||||
elseif time>Yaw_cmd_t[1] then
|
||||
|
||||
int_yaw := DYaw_cmd;
|
||||
IndicatorYawConsign := true;
|
||||
|
||||
else
|
||||
|
||||
int_yaw := 0;
|
||||
IndicatorYawConsign := false;
|
||||
|
||||
end if;*/
|
||||
equation
|
||||
// remote control filter with Tcst time constant
|
||||
der(VerticalSpeedCommand) = (VerticalSpeedCommand_i - VerticalSpeedCommand) / Tcst;
|
||||
der(RollCommand) = (RollCommand_i - RollCommand) / Tcst;
|
||||
der(PitchCommand) = (PitchCommand_i - PitchCommand) / Tcst;
|
||||
der(YawCommand) = (YawCommand_i - YawCommand) / Tcst;
|
||||
/* initial code of Andrii VAKULKO, destined to be used with manual button included in the SimulationX interface
|
||||
if VSCommand1 > 0 then
|
||||
VerticalSpeedCommand = -1;
|
||||
elseif VSCommand2 > 0 then
|
||||
VerticalSpeedCommand = -0.8;
|
||||
elseif VSCommand3 > 0 then
|
||||
VerticalSpeedCommand = -0.6;
|
||||
elseif VSCommand4 > 0 then
|
||||
VerticalSpeedCommand = -0.4;
|
||||
elseif VSCommand5 > 0 then
|
||||
VerticalSpeedCommand = -0.2;
|
||||
elseif VSCommand6 > 0 then
|
||||
VerticalSpeedCommand = 0.2;
|
||||
elseif VSCommand7 > 0 then
|
||||
VerticalSpeedCommand = 0.4;
|
||||
elseif VSCommand8 > 0 then
|
||||
VerticalSpeedCommand = 0.6;
|
||||
elseif VSCommand9 > 0 then
|
||||
VerticalSpeedCommand = 0.8;
|
||||
elseif VSCommand10 > 0 then
|
||||
VerticalSpeedCommand = 1;
|
||||
else
|
||||
VerticalSpeedCommand = 0;
|
||||
end if;
|
||||
|
||||
if YCommandP > 0 then
|
||||
der(YawCommand) = 0.01;
|
||||
//IndicatorYawConsign = true;
|
||||
elseif YCommandM > 0 then
|
||||
der(YawCommand) = -0.01;
|
||||
//IndicatorYawConsign = true;
|
||||
else
|
||||
YawCommand = 0;
|
||||
//IndicatorYawConsign = false;
|
||||
end if;
|
||||
|
||||
if RCommandP > 0 then
|
||||
RollCommand = 0.0261799; //15 deg
|
||||
elseif RCommandM > 0 then
|
||||
RollCommand = -0.0261799;
|
||||
else
|
||||
RollCommand = 0;
|
||||
end if;
|
||||
|
||||
if PCommandP > 0 then
|
||||
PitchCommand = 0.0261799;
|
||||
elseif PCommandM > 0 then
|
||||
PitchCommand = -0.0261799;
|
||||
else
|
||||
PitchCommand = 0;
|
||||
end if;*/
|
||||
annotation(
|
||||
VerticalSpeedCommand(flags=2),
|
||||
RollCommand(flags=2),
|
||||
PitchCommand(flags=2),
|
||||
YawCommand(flags=2),
|
||||
ControlMode(flags=2),
|
||||
IndicatorYawConsign(flags=2),
|
||||
Icon(
|
||||
coordinateSystem(extent={{-125,-100},{125,100}}),
|
||||
graphics={
|
||||
Rectangle(
|
||||
fillColor={255,255,255},
|
||||
fillPattern=FillPattern.Solid,
|
||||
extent={{-123.3,100},{123.3,-100}}),
|
||||
Text(
|
||||
textString="%name",
|
||||
fillPattern=FillPattern.None,
|
||||
extent={{-86,20},{86,-20}},
|
||||
origin={-2,6})}),
|
||||
experiment(
|
||||
StopTime=10,
|
||||
StartTime=0,
|
||||
Interval=0.02,
|
||||
MaxInterval="0.001"));
|
||||
end RemoteControl;
|
||||
@@ -0,0 +1,78 @@
|
||||
model AIDA_System "AIDAModel-integrationProSivic_reference.isx"
|
||||
AIDAModelica.QuadcopterModel quadcopterModel1(rigidBodyKinematicModel1(computeDronePosition1(integrator10(initType = Modelica.Blocks.Types.Init.SteadyState, y_start = -0.29), integrator11(initType = Modelica.Blocks.Types.Init.InitialOutput, y_start = 39), integrator12(initType = Modelica.Blocks.Types.Init.InitialOutput))), rigidBodyDynamicModel1(computeDroneVelocity1(integrator4(initType = Modelica.Blocks.Types.Init.SteadyState)))) annotation(
|
||||
Placement(visible = true, transformation(origin = {16.4, 7.25}, extent = {{-10.6, -13.25}, {10.6, 13.25}}, rotation = 0)));
|
||||
AIDAModelica.LowLevelFlightControlSystem lowLevelFlightControlSystem1(controlAltitude1(computeAltitudeConsign1(PID1(k = 30, Ti = 1, Td = 0.1, Nd = 10, initType = Modelica.Blocks.Types.InitPID.InitialOutput)), pID_2(k = 25, Ti = 0.5, Td = 0.08, initType = Modelica.Blocks.Types.InitPID.InitialOutput)), attitudeControl1(Test_CstMomentumActiv = false, Test_open_loop = {false, false, false}, controlRollAngle1(xAngularSpeedErrorModel1(Kwphi = 1.5), PID(k = 0.07, Ti = 30, Td = 0.02, Nd = 0.1, initType = Modelica.Blocks.Types.InitPID.InitialOutput, Add(k1 = 1, k2 = 1, k3 = 1))), controlPitchAngle1(yAngularSpeedErrorModel1(Kwteta = 1.5, RTStepConsign = false), PID1(k = 0.07, Ti = 30, Td = 0.02, Nd = 0.1, initType = Modelica.Blocks.Types.InitPID.InitialOutput, Add(k1 = 1, k2 = 1, k3 = 1))), controlYawAngle1(zAngularSpeedErrorModel1(Kwyaw = 2), PID2(k = 0.04, Ti = 20, Td = 0.5, Nd = 2.5, initType = Modelica.Blocks.Types.InitPID.InitialOutput, Add(k1 = 1, k2 = 1, k3 = 1)))), positionControl1(controlSpeed1(PID(k = 0.8, Ti = 1, initType = Modelica.Blocks.Types.InitPID.InitialOutput), PID2(k = 0.8, Ti = 1, initType = Modelica.Blocks.Types.InitPID.InitialOutput), PID1(k = 30, Ti = 1, Td = 0.1, initType = Modelica.Blocks.Types.InitPID.InitialOutput)))) annotation(
|
||||
Placement(visible = true, transformation(origin = {-2.96, 1.52}, extent = {{-34.04, -5.52}, {-11.04, 17.48}}, rotation = 0)));
|
||||
AIDAModelica.ControlDroneNavigation controlDroneNavigation1 annotation(
|
||||
Placement(visible = true, transformation(origin = {15.9, 0.3}, extent = {{-86.9, -3.3}, {-64.9, 18.7}}, rotation = 0)));
|
||||
AIDAModelica.RemoteControl remoteControl1(VS_cmd = -0.5, Pitch_cmd = 0.02, VS_cmd_t = {1000, 1001}, Roll_cmd_t = {1000, 1001}, Pitch_cmd_t = {1000, 1001}, Yaw_cmd_t = {1000, 1001}, Auto_Ctl_t = 0.1) annotation(
|
||||
Placement(visible = true, transformation(extent = {{-37, 29}, {-12, 49}}, rotation = 0)));
|
||||
AIDAModelica.WindProfile windProfile1 annotation(
|
||||
Placement(visible = true, transformation(origin = {16, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
|
||||
Requirements.StabilityRequirement stabilityRequirement1 annotation(
|
||||
Placement(visible = true, transformation(origin = {-44, -32}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
|
||||
equation
|
||||
connect(windProfile1.Fy, quadcopterModel1.Fy) annotation(
|
||||
Line(points = {{21, 29}, {22, 29}, {22, 22}}, color = {0, 0, 127}));
|
||||
connect(windProfile1.Fx, quadcopterModel1.Fx) annotation(
|
||||
Line(points = {{11, 29}, {11, 26.5}, {12, 26.5}, {12, 22}}, color = {0, 0, 127}));
|
||||
connect(remoteControl1.RollCommand, lowLevelFlightControlSystem1.RCAttitudeCommands[1]) annotation(
|
||||
Line(points = {{-27, 29}, {-27, 19}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(remoteControl1.PitchCommand, lowLevelFlightControlSystem1.RCAttitudeCommands[2]) annotation(
|
||||
Line(points = {{-22, 29}, {-22, 22}, {-27, 22}, {-27, 19}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(lowLevelFlightControlSystem1.RCVerticalSpeedCommand, remoteControl1.VerticalSpeedCommand) annotation(
|
||||
Line(points = {{-31, 19}, {-31.75, 19}, {-31.75, 29}, {-32, 29}}, color = {0, 0, 127}));
|
||||
connect(remoteControl1.YawCommand, lowLevelFlightControlSystem1.RCYawCommand) annotation(
|
||||
Line(points = {{-17, 29}, {-18, 29}, {-18, 20}, {-24, 20}, {-24, 18}}, color = {0, 0, 127}));
|
||||
connect(remoteControl1.ControlMode, controlDroneNavigation1.APEngagement) annotation(
|
||||
Line(points = {{-37, 34}, {-76, 34}, {-76, 14}, {-71, 14}}, color = {255, 0, 255}, thickness = 0.015625));
|
||||
connect(remoteControl1.IndicatorYawConsign, controlDroneNavigation1.IndicatorYawConsign) annotation(
|
||||
Line(points = {{-37, 39}, {-78, 39}, {-78, 8}, {-71, 8}}, color = {255, 0, 255}));
|
||||
connect(quadcopterModel1.Attitude[3], stabilityRequirement1.yaw) annotation(
|
||||
Line(points = {{28, 12}, {44, 12}, {44, -31}, {-34, -31}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.YawConsign, stabilityRequirement1.yawConsign) annotation(
|
||||
Line(points = {{-50, 8}, {-48, 8}, {-48, -22}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Position[1], stabilityRequirement1.posX) annotation(
|
||||
Line(points = {{28, 8}, {48, 8}, {48, -26}, {-34, -26}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Position[2], stabilityRequirement1.posY) annotation(
|
||||
Line(points = {{28, 8}, {48, 8}, {48, -38}, {-34, -38}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.DronPositionConsign[1], stabilityRequirement1.DronePositionConsign[1]) annotation(
|
||||
Line(points = {{-50, 14}, {-44, 14}, {-44, -22}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.DronPositionConsign[2], stabilityRequirement1.DronePositionConsign[2]) annotation(
|
||||
Line(points = {{-50, 14}, {-44, 14}, {-44, -22}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.DronPositionConsign[3], stabilityRequirement1.DronePositionConsign[3]) annotation(
|
||||
Line(points = {{-50, 14}, {-44, 14}, {-44, -22}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.Yaw, quadcopterModel1.Attitude[3]) annotation(
|
||||
Line(points = {{-71, 3}, {-75, 3}, {-75, -18}, {39, -18}, {39, 12}, {28, 12}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Speed[:], lowLevelFlightControlSystem1.Speed[:]) annotation(
|
||||
Line);
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand1, quadcopterModel1.ThrottleCommand1) annotation(
|
||||
Line(points = {{-14, 14}, {6, 14}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand2, quadcopterModel1.ThrottleCommand2) annotation(
|
||||
Line(points = {{-14, 10}, {-5.5, 10}, {-5.5, 9}, {6, 9}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand3, quadcopterModel1.ThrottleCommand3) annotation(
|
||||
Line(points = {{-14, 6}, {-5, 6}, {-5, 5}, {6, 5}}, color = {0, 0, 127}));
|
||||
connect(lowLevelFlightControlSystem1.ThrottleCommand4, quadcopterModel1.ThrottleCommand4) annotation(
|
||||
Line(points = {{-14, 0}, {-3.5, 0}, {-3.5, 1}, {6, 1}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Accelerations, lowLevelFlightControlSystem1.Accelerations) annotation(
|
||||
Line(points = {{28, -1}, {30, -1}, {30, -8}, {-18, -8}, {-18, -4}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Speed, lowLevelFlightControlSystem1.Speed) annotation(
|
||||
Line(points = {{28, 3}, {32, 3}, {32, -10}, {-22, -10}, {-22, -4}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Position, lowLevelFlightControlSystem1.Position) annotation(
|
||||
Line(points = {{28, 7}, {34, 7}, {34, -12}, {-26, -12}, {-26, -4}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.Attitude, lowLevelFlightControlSystem1.Attitude) annotation(
|
||||
Line(points = {{28, 12}, {36, 12}, {36, -14}, {-29, -14}, {-29, -4}}, color = {0, 0, 127}));
|
||||
connect(quadcopterModel1.AngularVelocities, lowLevelFlightControlSystem1.AngularSpeed) annotation(
|
||||
Line(points = {{28, 16}, {42, 16}, {42, -16}, {-33, -16}, {-33, -4}}, color = {0, 0, 127}));
|
||||
connect(controlDroneNavigation1.YawConsign, lowLevelFlightControlSystem1.YawConsign) annotation(
|
||||
Line(points = {{-49, 8}, {-45, 8}, {-45, 5}, {-37, 5}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(controlDroneNavigation1.DronPositionConsign[:], lowLevelFlightControlSystem1.DronePositionConsign[:]) annotation(
|
||||
Line(points = {{-49, 14}, {-37, 14}}, color = {0, 0, 127}, thickness = 0.0625));
|
||||
connect(lowLevelFlightControlSystem1.SelectedControlMode, controlDroneNavigation1.SelectedControlMode) annotation(
|
||||
Line(points = {{-37, 1}, {-43, 1}, {-43, 3}, {-49, 3}}, color = {255, 0, 255}, thickness = 0.0625));
|
||||
annotation(
|
||||
Icon(coordinateSystem(grid = {3, 2})),
|
||||
experiment(StartTime = 0, StopTime = 30, Tolerance = 1e-06, Interval = 0.002),
|
||||
__OpenModelica_simulationFlags(jacobian = "coloredNumerical", s = "dassl", lv = "LOG_STATS"),
|
||||
uses(Modelica(version = "3.2.2")));
|
||||
end AIDA_System;
|
||||
@@ -12,6 +12,7 @@ model ControlMotor "[SF1.1/2/3/4.1] Control motor"
|
||||
equation
|
||||
// enter your equations here
|
||||
ComdKD = (DAngVel - wb) / cR;
|
||||
|
||||
annotation(
|
||||
Icon(graphics = {Rectangle(fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {103.3, -100}}), Text(origin = {-7, 44}, extent = {{-39, 12}, {39, -12}}, textString = "%name")}, coordinateSystem(initialScale = 0.1)));
|
||||
end ControlMotor;
|
||||
1720
SimulationModels/OpenModelica 1.11/AIDAModelica/QuadcopterModel.mo
Normal file
1720
SimulationModels/OpenModelica 1.11/AIDAModelica/QuadcopterModel.mo
Normal file
File diff suppressed because it is too large
Load Diff
164
SimulationModels/OpenModelica 1.11/AIDAModelica/RemoteControl.mo
Normal file
164
SimulationModels/OpenModelica 1.11/AIDAModelica/RemoteControl.mo
Normal file
@@ -0,0 +1,164 @@
|
||||
within AIDAModelica;
|
||||
|
||||
model RemoteControl "RemoteControl"
|
||||
// CP: 65001
|
||||
// SimulationX Version: 3.8.2.45319 x64
|
||||
Real VerticalSpeedCommand_i(start = 0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput VerticalSpeedCommand(quantity = "Mechanics.Translation.Velocity", displayUnit = "m/s") "'output Real' as connector" annotation(
|
||||
Placement(transformation(extent = {{12, 28}, {32, 48}}), iconTransformation(origin = {-75, -100}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Real RollCommand_i(start = 0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput RollCommand(quantity = "Mechanics.Rotation.Angle", displayUnit = "rad") "'output Real' as connector" annotation(
|
||||
Placement(transformation(extent = {{56, 8}, {76, 28}}), iconTransformation(origin = {-25, -100}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Real PitchCommand_i(start = 0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput PitchCommand(quantity = "Mechanics.Rotation.Angle", displayUnit = "rad") "'output Real' as connector" annotation(
|
||||
Placement(transformation(extent = {{-38, -46}, {-18, -26}}), iconTransformation(origin = {25, -100}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Real YawCommand_i(start = 0) "commande interne non filtree";
|
||||
Modelica.Blocks.Interfaces.RealOutput YawCommand(quantity = "Mechanics.Rotation.Angle", displayUnit = "rad") "'output Real' as connector" annotation(
|
||||
Placement(transformation(extent = {{18, -52}, {38, -32}}), iconTransformation(origin = {75, -100}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput ControlMode "'output Boolean' as connector" annotation(
|
||||
Placement(transformation(extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-125, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput IndicatorYawConsign "'output Boolean' as connector" annotation(
|
||||
Placement(transformation(origin = {-45, 45}, extent = {{-17, -17}, {17, 17}}), iconTransformation(origin = {-125, 0}, extent = {{-10, -10}, {10, 10}}, rotation = -180)));
|
||||
parameter Real VS_cmd = 0.5;
|
||||
parameter Real[2] VS_cmd_t = {3, 5} "Instants de démarrage et fin du step";
|
||||
parameter Real Pitch_cmd = 0.03;
|
||||
parameter Real[2] Pitch_cmd_t = {1, 4} "Instants de démarrage et fin du step, après stabilisation verticale";
|
||||
parameter Real Yaw_cmd = 0.5;
|
||||
parameter Real[2] Yaw_cmd_t = {6, 8} "Instants de démarrage et fin du step";
|
||||
parameter Real Roll_cmd = 0.2 "Amplitude step ";
|
||||
parameter Real Roll_cmd_t[2] = {1, 100} "Instants de démarrage et fin du step";
|
||||
parameter Real Tcst = 0.1 "constante de temps pour filter les sorties du remote ctl";
|
||||
Boolean Auto_Ctl_Enabled(start = true);
|
||||
parameter Real Auto_Ctl_t = 0.1 "Instant de déclenchement du mode auto";
|
||||
initial equation
|
||||
PitchCommand = 0;
|
||||
RollCommand = 0;
|
||||
YawCommand = 0;
|
||||
VerticalSpeedCommand = 0;
|
||||
PitchCommand_i = 0;
|
||||
RollCommand_i = 0;
|
||||
YawCommand_i = 0;
|
||||
VerticalSpeedCommand_i = 0;
|
||||
ControlMode = false;
|
||||
IndicatorYawConsign = false;
|
||||
Auto_Ctl_Enabled = true;
|
||||
algorithm
|
||||
when time > Auto_Ctl_t and Auto_Ctl_Enabled == true then
|
||||
ControlMode := true;
|
||||
end when;
|
||||
when time > VS_cmd_t[1] then
|
||||
VerticalSpeedCommand_i := VS_cmd;
|
||||
ControlMode := false;
|
||||
Auto_Ctl_Enabled := false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] then
|
||||
VerticalSpeedCommand_i := 0;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] + Pitch_cmd_t[1] then
|
||||
PitchCommand_i := Pitch_cmd;
|
||||
ControlMode := false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] + Pitch_cmd_t[2] then
|
||||
PitchCommand_i := 0;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] + Roll_cmd_t[1] then
|
||||
RollCommand_i := Roll_cmd;
|
||||
ControlMode := false;
|
||||
end when;
|
||||
when time > VS_cmd_t[2] + Roll_cmd_t[2] then
|
||||
RollCommand_i := 0;
|
||||
end when;
|
||||
//Yaw command
|
||||
when time > VS_cmd_t[2] + Yaw_cmd_t[1] then
|
||||
YawCommand_i := Yaw_cmd;
|
||||
ControlMode := false;
|
||||
IndicatorYawConsign := true;
|
||||
end when;
|
||||
//IndicatorYawConsign := true;
|
||||
when time > VS_cmd_t[2] + Yaw_cmd_t[2] then
|
||||
YawCommand_i := 0;
|
||||
end when;
|
||||
//IndicatorYawConsign := false;
|
||||
/*if time>Yaw_cmd_t[2] then
|
||||
|
||||
int_yaw := 0;
|
||||
IndicatorYawConsign := false;
|
||||
|
||||
elseif time>Yaw_cmd_t[1] then
|
||||
|
||||
int_yaw := DYaw_cmd;
|
||||
IndicatorYawConsign := true;
|
||||
|
||||
else
|
||||
|
||||
int_yaw := 0;
|
||||
IndicatorYawConsign := false;
|
||||
|
||||
end if;*/
|
||||
equation
|
||||
// remote control filter with Tcst time constant
|
||||
der(VerticalSpeedCommand) = (VerticalSpeedCommand_i - VerticalSpeedCommand) / Tcst;
|
||||
der(RollCommand) = (RollCommand_i - RollCommand) / Tcst;
|
||||
der(PitchCommand) = (PitchCommand_i - PitchCommand) / Tcst;
|
||||
der(YawCommand) = (YawCommand_i - YawCommand) / Tcst;
|
||||
/* initial code of Andrii VAKULKO, destined to be used with manual button included in the SimulationX interface
|
||||
if VSCommand1 > 0 then
|
||||
VerticalSpeedCommand = -1;
|
||||
elseif VSCommand2 > 0 then
|
||||
VerticalSpeedCommand = -0.8;
|
||||
elseif VSCommand3 > 0 then
|
||||
VerticalSpeedCommand = -0.6;
|
||||
elseif VSCommand4 > 0 then
|
||||
VerticalSpeedCommand = -0.4;
|
||||
elseif VSCommand5 > 0 then
|
||||
VerticalSpeedCommand = -0.2;
|
||||
elseif VSCommand6 > 0 then
|
||||
VerticalSpeedCommand = 0.2;
|
||||
elseif VSCommand7 > 0 then
|
||||
VerticalSpeedCommand = 0.4;
|
||||
elseif VSCommand8 > 0 then
|
||||
VerticalSpeedCommand = 0.6;
|
||||
elseif VSCommand9 > 0 then
|
||||
VerticalSpeedCommand = 0.8;
|
||||
elseif VSCommand10 > 0 then
|
||||
VerticalSpeedCommand = 1;
|
||||
else
|
||||
VerticalSpeedCommand = 0;
|
||||
end if;
|
||||
|
||||
if YCommandP > 0 then
|
||||
der(YawCommand) = 0.01;
|
||||
//IndicatorYawConsign = true;
|
||||
elseif YCommandM > 0 then
|
||||
der(YawCommand) = -0.01;
|
||||
//IndicatorYawConsign = true;
|
||||
else
|
||||
YawCommand = 0;
|
||||
//IndicatorYawConsign = false;
|
||||
end if;
|
||||
|
||||
if RCommandP > 0 then
|
||||
RollCommand = 0.0261799; //15 deg
|
||||
elseif RCommandM > 0 then
|
||||
RollCommand = -0.0261799;
|
||||
else
|
||||
RollCommand = 0;
|
||||
end if;
|
||||
|
||||
if PCommandP > 0 then
|
||||
PitchCommand = 0.0261799;
|
||||
elseif PCommandM > 0 then
|
||||
PitchCommand = -0.0261799;
|
||||
else
|
||||
PitchCommand = 0;
|
||||
end if;*/
|
||||
annotation(
|
||||
VerticalSpeedCommand(flags = 2),
|
||||
RollCommand(flags = 2),
|
||||
PitchCommand(flags = 2),
|
||||
YawCommand(flags = 2),
|
||||
ControlMode(flags = 2),
|
||||
IndicatorYawConsign(flags = 2),
|
||||
Icon(coordinateSystem(extent = {{-125, -100}, {125, 100}}, initialScale = 0.1), graphics = {Rectangle(fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-123.3, 100}, {123.3, -100}}), Text(origin = {-12, 10}, extent = {{-78, 18}, {86, -20}}, textString = "RemoteControl")}),
|
||||
experiment(StopTime = 10, StartTime = 0, Interval = 0.02, MaxInterval = "0.001"));
|
||||
end RemoteControl;
|
||||
@@ -0,0 +1,19 @@
|
||||
within AIDAModelica;
|
||||
|
||||
model WindProfile
|
||||
Modelica.Blocks.Sources.Constant const(k = 0) annotation(
|
||||
Placement(visible = true, transformation(origin = {-54, -30}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Modelica.Blocks.Sources.Constant const1(k = 0) annotation(
|
||||
Placement(visible = true, transformation(origin = {50, -30}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Modelica.Blocks.Interfaces.RealOutput Fx annotation(
|
||||
Placement(visible = true, transformation(origin = {-50, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -90), iconTransformation(origin = {-50, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
Modelica.Blocks.Interfaces.RealOutput Fy annotation(
|
||||
Placement(visible = true, transformation(origin = {50, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -90), iconTransformation(origin = {50, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
|
||||
equation
|
||||
connect(const.y, Fx) annotation(
|
||||
Line(points = {{-54, -41}, {-54, -75.5}, {-50, -75.5}, {-50, -110}}, color = {0, 0, 127}));
|
||||
connect(const1.y, Fy) annotation(
|
||||
Line(points = {{50, -41}, {50, -110}}, color = {0, 0, 127}));
|
||||
|
||||
annotation(
|
||||
Icon(graphics = {Rectangle(extent = {{-100, 100}, {100, -100}}), Text(origin = {-23, 18}, extent = {{57, -26}, {-11, 4}}, textString = "WindProfile")}));end WindProfile;
|
||||
14790
SimulationModels/OpenModelica 1.11/AIDAModelica/package.mo
Normal file
14790
SimulationModels/OpenModelica 1.11/AIDAModelica/package.mo
Normal file
File diff suppressed because it is too large
Load Diff
@@ -68,3 +68,4 @@ YAngularSpeedErrorModel
|
||||
YawConsignProducing
|
||||
ZAngularSpeedErrorModel
|
||||
ModelicaLicense2
|
||||
WindProfile
|
||||
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.bmp
Normal file
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 MiB |
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.pdf
Normal file
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.pdf
Normal file
Binary file not shown.
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.png
Normal file
BIN
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
6662
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.svg
Normal file
6662
SimulationModels/OpenModelica 1.11/Requirements/AIDA_System.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 286 KiB |
@@ -0,0 +1,102 @@
|
||||
within Requirements;
|
||||
|
||||
model StabilityRequirement
|
||||
"SR-WIND-02: The UAS shall maintain lateral and yaw stability under wind disturbance and recover within limits"
|
||||
|
||||
// ---- System-level parameters (traceable to SR-WIND-02) ----
|
||||
parameter Real hoverTolerance = 2.5
|
||||
"Maximum allowed lateral deviation during hover [m]";
|
||||
parameter Real yawTolerance = 5
|
||||
"Maximum allowed yaw error [deg]";
|
||||
parameter Real recoveryBand = 0.5
|
||||
"Position error band for recovery after disturbance [m]";
|
||||
parameter Real recoveryTime = 3
|
||||
"Time to remain within recovery band [s]";
|
||||
|
||||
// ---- Inputs from the system ----
|
||||
Modelica.Blocks.Interfaces.RealInput posX
|
||||
"Measured X position [m]" annotation(
|
||||
Placement(transformation(extent={{120,40},{80,80}})));
|
||||
Modelica.Blocks.Interfaces.RealInput posY
|
||||
"Measured Y position [m]" annotation(
|
||||
Placement(transformation(extent={{120,-80},{80,-40}})));
|
||||
Modelica.Blocks.Interfaces.RealInput yaw
|
||||
"Measured yaw angle [deg]" annotation(
|
||||
Placement(transformation(extent={{120,-10},{80,30}})));
|
||||
Modelica.Blocks.Interfaces.RealInput DronePositionConsign[3]
|
||||
"Commanded reference position [m]" annotation(
|
||||
Placement(transformation(extent={{-20,120},{20,80}}, rotation=-90)));
|
||||
Modelica.Blocks.Interfaces.RealInput yawConsign
|
||||
"Commanded yaw angle [deg]" annotation(
|
||||
Placement(transformation(extent={{-60,120},{-20,80}}, rotation=-90)));
|
||||
|
||||
// ---- Outputs for monitoring ----
|
||||
Modelica.Blocks.Interfaces.RealOutput lateralError
|
||||
"2D lateral position error magnitude [m]" annotation(
|
||||
Placement(transformation(extent={{-90,50},{-110,70}})));
|
||||
Modelica.Blocks.Interfaces.RealOutput yawError
|
||||
"Yaw error magnitude [deg]" annotation(
|
||||
Placement(transformation(extent={{-90,20},{-110,40}})));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput withinHoverLimit
|
||||
"true if lateralError < hoverTolerance" annotation(
|
||||
Placement(visible = true, transformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput withinYawLimit
|
||||
"true if yawError < yawTolerance" annotation(
|
||||
Placement(visible = true, transformation(extent = {{-110, -40}, {-90, -20}}, rotation = 0), iconTransformation(origin = {-100, -30}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput recovered
|
||||
"true if position remains within recoveryBand for recoveryTime" annotation(
|
||||
Placement(visible = true, transformation(extent = {{-110, -70}, {-90, -50}}, rotation = 0), iconTransformation(origin = {-100, -60}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
|
||||
Modelica.Blocks.Interfaces.BooleanOutput pass
|
||||
"true if all criteria are satisfied" annotation(
|
||||
Placement(visible = true, transformation(extent = {{-110, -100}, {-90, -80}}, rotation = 0), iconTransformation(origin = {-100, -90}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
|
||||
|
||||
protected
|
||||
Real t_within(start=0) "Timer for recovery criterion";
|
||||
equation
|
||||
// --- Lateral and yaw errors ---
|
||||
lateralError = sqrt((posX - DronePositionConsign[1])^2 +
|
||||
(posY - DronePositionConsign[2])^2);
|
||||
yawError = abs(yaw - yawConsign);
|
||||
|
||||
withinHoverLimit = lateralError < hoverTolerance;
|
||||
withinYawLimit = yawError < yawTolerance;
|
||||
|
||||
// --- Recovery logic (after gust disturbance) ---
|
||||
der(t_within) = if lateralError < recoveryBand then 1 else 0;
|
||||
|
||||
// Reset timer whenever the drone leaves the recovery band
|
||||
when lateralError > recoveryBand then
|
||||
reinit(t_within, 0);
|
||||
end when;
|
||||
|
||||
recovered = t_within >= recoveryTime;
|
||||
|
||||
// --- Overall requirement pass flag ---
|
||||
//pass = withinHoverLimit and withinYawLimit and recovered;
|
||||
pass = withinHoverLimit and withinYawLimit;
|
||||
annotation(
|
||||
Documentation(info="
|
||||
<html>
|
||||
<h4>SR-WIND-02 – Performance in Wind</h4>
|
||||
<p>
|
||||
Source: EASA Means of Compliance Light-UAS.2512,
|
||||
ISO 21384-3 (Clause 10 – Operational limitations).
|
||||
</p>
|
||||
<p>
|
||||
<b>Requirement:</b><br>
|
||||
Under a steady 8 m/s wind with 12 m/s gusts, the UAS shall:
|
||||
<ul>
|
||||
<li>Maintain lateral position error ≤ 1.5 m (95th percentile) during hover.</li>
|
||||
<li>Maintain yaw pointing error ≤ 5° (95th percentile).</li>
|
||||
<li>Recover to within 0.5 m position error within 3 s after gust disturbance.</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<b>Simulation Inputs:</b> Connect to AIDA_System position, yaw, and
|
||||
reference signals.
|
||||
</p>
|
||||
</html>"),
|
||||
uses(Modelica(version="3.2.2")),
|
||||
Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "SR-WIND-02"), Rectangle(extent = {{-104, -2}, {-104, -2}}), Rectangle(origin = {0, -1}, extent = {{-100, 101}, {100, -99}})}, coordinateSystem(initialScale = 0.1)));
|
||||
|
||||
end StabilityRequirement;
|
||||
@@ -0,0 +1,3 @@
|
||||
package Requirements
|
||||
|
||||
end Requirements;
|
||||
2289
SimulationModels/OpenModelica 1.11/images/AIDA_System.eps
Normal file
2289
SimulationModels/OpenModelica 1.11/images/AIDA_System.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
SimulationModels/OpenModelica 1.11/images/AIDA_System.pdf
Normal file
BIN
SimulationModels/OpenModelica 1.11/images/AIDA_System.pdf
Normal file
Binary file not shown.
4559
SimulationModels/OpenModelica 1.11/images/AIDA_System.svg
Normal file
4559
SimulationModels/OpenModelica 1.11/images/AIDA_System.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 234 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user