Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Features added to the Avl Automation #61

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions tools/avl_automation/README.md
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Purpose

The idea of this tool is to automate the writing of the Advanced Lift Drag plugin by automatizing the coefficient generation and requiring minimal user calculations.
The idea of this tool is to automate the writing of the Advanced Lift Drag plugin by automatizing the coefficient generation and requiring minimal user calculations as well as create the necessary files to run a simulation in gazebo.

## Setup

Expand Down Expand Up @@ -28,15 +28,15 @@ If you want to move the location of the AVL directory, this can simply be done b

To run the tool all that is needed is to modify the `input.yml` to the plane that you desire and then run `python input_avl.py <your_custom_yaml_file>.yml` Note that you require to have the yaml and argparse packages in your python environment to run this. An example template has been provided in the form of the `input.yml` that implements a standard plane with two ailerons, an elevator and a rudder. This example template can be run using: `python input_avl.py --yaml_file input.yml`.
Once the script has been executed, the generated .avl, .sdf and a plot of the proposed control surfaces can be found in <your-planes-name> directory. The sdf file is the generated Advanced Lift Drag Plugin that can be copied and pasted straight into a model.sdf file, which can then be run in Gazebo.
The created init.d-posix file can be placed inside the `PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix` folder with the apropiate name note that this same file needs to be added to the CMakeLists

## Functionality

The tool first asks the user for a range of vehicle specific parameters that are needed in order to specify the geometry and physical properties of the plane. The user has the choice to define a completely custom model, or alternatively select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and then provide only some physical properties, without having to define the entire model themselves. The input_avl.py file takes the provided parameter and creates an .avl file from this that can be read by AVL (the program). This happens in the process.sh file. The necessary output generated by AVL will be saved in two files: custom_vehicle_body_axis_derivatives.txt and custom_vehicle_stability_derivatives.txt. These two files contain the parameters that are required in order to populate the Advanced Lift Drag Plugin. Finally, avl_out_parse.py reads the generated .txt files and accordingly assigns parameters to the correct element in sdf. Once this is done, it is only a question of copy and pasting the generated Advanced Lift Drag plugin (found as <custom_plane>.sdf into the desired model.sdf file. )


## Usability

The current implementation provides a minimal working example. More accurate measurements can be made by adjusting the chosen number of vortices along span and chord according to desired preferences. A good starting point for this can be found here: <https://www.redalyc.org/pdf/6735/673571173005.pdf>. Furthermore, one can also more accurately model a vehicle by using a larger number of sections. In the current .yml file, only a left and right edge are defined for each surface yielding exactly one section, but the code supports expanding this to any number of desired sections.
The current implementation provides a minimal working example as well as a more feature complete example. More accurate measurements can be made by adjusting the chosen number of vortices along span and chord according to desired preferences. A good starting point for this can be found here: <https://www.redalyc.org/pdf/6735/673571173005.pdf>. Furthermore, one can also more accurately model a vehicle by using a larger number of sections. In the current .yml file, only a left and right edge are defined for each surface yielding exactly one section, but the code supports expanding this to any number of desired sections.

## IMPORTANT POINTS TO NOTE

Expand Down Expand Up @@ -143,7 +143,6 @@ Cnd{i} -> Cen_ctrl Effect of the control surface's deflection on yaw moment

The tool, while self-contained, could be expanded into multiple directions.

1. Currently hinge positions and gains are set at default levels, and these could, if desired be further customized for more control.
2. More vehicles could be added to provide default templates that require less input. At the moment, only "custom" works completely.
3. Fuselage modelling could be included to further improve the accuracy of calculated coefficients.
4. At the moment only NACA airfoils are provided as a way to generate cambered surfaces. An alternative to this would be to use custom airfoil files.
1. More vehicles could be added to provide default templates that require less input. At the moment, only "custom" works completely.
2. Fuselage modelling could be included to further improve the accuracy of calculated coefficients.
3. At the moment only NACA airfoils are provided as a way to generate cambered surfaces. An alternative to this would be to use custom airfoil files.
Binary file not shown.
Binary file not shown.
49 changes: 22 additions & 27 deletions tools/avl_automation/avl_out_parse.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,15 @@
value (str): The value associated with the desired coefficient.

"""
def get_coef(file: TextIO,token: str) -> str:

linesplit = []
def get_coef(file: TextIO, token: str) -> str:
line_parts = []
for line in file:
if f' {token} ' in line:
linesplit = line.split()
break

index = 0
for i,v in enumerate(linesplit):
if v == token:
index = i
value = linesplit[index+2]
return value
line_parts = line.split(f'{token} =')
if len(line_parts) > 1:
value = line_parts[1].split()[0] # Extract the value after the '='
return value
raise ValueError(f"Token '{token}' not found in file")



Expand Down Expand Up @@ -80,15 +75,14 @@ def ctrl_surface_coef(file: TextIO,ctrl_surface_vec: list,index: str, direction:
# Insert necessary coefficient values, index and direction in correct sdf location.
extracted_text = extracted_text.replace("<name></name>",f'<name>servo_{index}</name>')
extracted_text = extracted_text.replace("<index></index>",f'<index>{index}</index>')
extracted_text = extracted_text.replace("<direction></direction>",f'<directon>{direction}</direction>')
extracted_text = extracted_text.replace("<direction></direction>",f'<direction>{direction}</direction>')
extracted_text = extracted_text.replace("<CD_ctrl></CD_ctrl>",f'<CD_ctrl>{ctrl_surface_vec[0]}</CD_ctrl>')
extracted_text = extracted_text.replace("<CY_ctrl></CY_ctrl>",f'<CY_ctrl>{ctrl_surface_vec[1]}</CY_ctrl>')
extracted_text = extracted_text.replace("<CL_ctrl></CL_ctrl>",f'<CL_ctrl>{ctrl_surface_vec[2]}</CL_ctrl>')
extracted_text = extracted_text.replace("<Cell_ctrl></Cell_ctrl>",f'<Cell_ctrl>{ctrl_surface_vec[3]}</Cell_ctrl>')
extracted_text = extracted_text.replace("<Cem_ctrl></Cem_ctrl>",f'<Cem_ctrl>{ctrl_surface_vec[4]}</Cem_ctrl>')
extracted_text = extracted_text.replace("<Cen_ctrl></Cen_ctrl>",f'<Cen_ctrl>{ctrl_surface_vec[5]}</Cen_ctrl>')


# Create model specific template
with open(file,'a') as plugin_file:
plugin_file.write(extracted_text + "\n")
Expand All @@ -108,7 +102,7 @@ def ctrl_surface_coef(file: TextIO,ctrl_surface_vec: list,index: str, direction:
ref_pt_z (str): The z coordinate of the reference point, at which forces and moments are applied.
num_ctrl_surfaces (str): The number of control surfaces that the model uses.
area (str): The wing surface area.
ctrl_surface_order (list): A list containing the types of control surfaces, in theorder in which
ctrl_surface_order (list): A list containing the types of control surfaces, in the order in which
they have been defined in the .avl file.
avl_path (str): A string containing the directory where the AVL directory should be moved to.

Expand Down Expand Up @@ -194,11 +188,11 @@ def main(file_name: TextIO, vehicle_type: str, AR: str, mac: str, ref_pt_x: str,

# Maybe in the future you want more types of set aircraft. Thus us a case differentiator.
match plane_type:

case "custom":
ctrl_surface_vec = []
with open(f'{filedir}custom_vehicle_body_axis_derivatives.txt') as bodyax_file:
original_position = bodyax_file.tell()
#NOTE: when creating 2 ailerons (left and right) only one ctrl_surface_vec is created (Is this correct??)
for i in range(1,(len(set(ctrl_surface_order)))+1):
ctrl_surface_vec = []
ctrl_surface_vec.append(get_coef(bodyax_file,f'CXd{i}'))
Expand All @@ -215,7 +209,10 @@ def main(file_name: TextIO, vehicle_type: str, AR: str, mac: str, ref_pt_x: str,
if not os.path.exists(f'{savedir}/{file_name}'):
os.makedirs(f'{savedir}/{file_name}')
file_name = f'{savedir}/{file_name}/{file_name}.sdf'
shutil.copy(f'{savedir}/templates/advanced_lift_drag_template.sdf',file_name)

with open('./templates/advanced_lift_drag_template.sdf', 'r') as source, open(file_name, 'a') as target:
content = source.read()
target.write(content)

# Get argument coefficients taken directly from the input file.
write_coef(file_name,"a0",alpha)
Expand Down Expand Up @@ -287,16 +284,15 @@ def main(file_name: TextIO, vehicle_type: str, AR: str, mac: str, ref_pt_x: str,
match plane_type:

case "custom":
for i, ctrl_surface in enumerate(ctrl_surface_order):

for i, ctrl_surface_type in enumerate(ctrl_surface_order):
# Check whether a particular type of control surface has been seen before. If it has,
# then the current control surface is the (right) counterpart. Depending on the exact
# nature of the encountered type you then need to negate the correct parameters.
if ctrl_surface in type_seen:
if ctrl_surface_type in type_seen:
# Work out what the corresponding index for the first encounter of the ctrl surface is.
seen_index = type_seen.index(ctrl_surface)

if ctrl_surface == 'aileron':
seen_index = type_seen.index(ctrl_surface_type)
if ctrl_surface_type == 'aileron':
#Change for right wing aileron by flipping sign
ctrl_surface_mat[seen_index][3] = -float(ctrl_surface_mat[0][3])
ctrl_surface_mat[seen_index][5] = -float(ctrl_surface_mat[0][5])
Expand All @@ -308,11 +304,10 @@ def main(file_name: TextIO, vehicle_type: str, AR: str, mac: str, ref_pt_x: str,
# If a ctrl surface has not been encountered add it to the type_seen list and
# set the index to the length of the list - 1 as this corresponds to the newest
# unseen element in ctrl_surface_mat .
type_seen.append(ctrl_surface)
type_seen.append(ctrl_surface_type)
seen_index = len(type_seen) - 1

ctrl_surface_coef(file_name,ctrl_surface_mat[seen_index],i,ctrl_direction[ctrl_surface])


ctrl_surface_coef(file_name,ctrl_surface_mat[seen_index],i,ctrl_direction[ctrl_surface_type])

# close the sdf file with plugin
with open(file_name,'a') as plugin_file:
Expand Down
Empty file modified tools/avl_automation/avl_steps.txt
100755 → 100644
Empty file.
165 changes: 165 additions & 0 deletions tools/avl_automation/easy_glider4/easy_glider4.avl
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
!***************************************
!easy_glider4 input dataset
!***************************************
easy_glider4
!Mach
0.0
!IYsym IZsym Zsym
0 0 0
!Sref Cref Bref
0.416 0.2311111111111111 1.8
!Xref Yref Zref
0 0 0


#--------------------------------------------------
SURFACE
left_wing
!Nchordwise Cspace Nspanwise Sspace
1 1 18 -2
TRANSLATE
0.275 0 0

ANGLE
4

#section_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0 0 0 0.205 0 1 -2
NACA
2412

#aileron_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.005 -0.31 0 0.2 0 8 -2
NACA
2412
CONTROL
aileron 1.0 0.8 0 1 0 -1

#aileron_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.035 -0.72 0 0.17 0 8 -2
NACA
2412
CONTROL
aileron 1.0 0.765 0 1 0 -1

#section_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.185 -0.885 0 0.02 0 1 -2
NACA
2412


#--------------------------------------------------
SURFACE
right_wing
!Nchordwise Cspace Nspanwise Sspace
1 1 18 -2
TRANSLATE
0.275 0 0

ANGLE
4

#section_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0 0 0 0.205 0 1 -2
NACA
2412

#aileron_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.005 0.31 0 0.2 0 8 -2
NACA
2412
CONTROL
aileron 1.0 0.8 0 1 0 -1

#aileron_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.035 0.72 0 0.17 0 8 -2
NACA
2412
CONTROL
aileron 1.0 0.765 0 1 0 -1

#section_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.185 0.885 0 0.02 0 1 -2
NACA
2412


#--------------------------------------------------
SURFACE
elevator
!Nchordwise Cspace Nspanwise Sspace
1 1 15 -1.25
TRANSLATE
0.96 0 0.15

YDUPLICATE
0.0


#elevator_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0 0 0 0.15 0 7 -1.25
NACA
2412
CONTROL
elevator 1.0 0.767 0 1 0 1

#elevator_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.06 0.165 0 0.09 0 7 -1.25
NACA
2412
CONTROL
elevator 1.0 0.611 0 1 0 1

#section_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.13 0.235 0 0.02 0 1 -1.25
NACA
2412


#--------------------------------------------------
SURFACE
rudder
!Nchordwise Cspace Nspanwise Sspace
1 1 14 -1.25
TRANSLATE
0.96 0 0.1

#rudder_begin
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0 0 0 0.14 0 7 -1.25
NACA
2412
CONTROL
rudder 1.0 0.571 0 0 1 1

#rudder_end
SECTION
!Xle Yle Zle Chord Ainc Nspanwise Sspace
0.12 0 0.29 0.02 0 7 -1.25
NACA
2412
CONTROL
rudder 1.0 0.9 0 0 1 1
Binary file added tools/avl_automation/easy_glider4/easy_glider4.ps
Binary file not shown.
Loading