peterdsharpe / AeroSandbox

Aircraft design optimization made fast through modern automatic differentiation. Composable analysis tools for aerodynamics, propulsion, structures, trajectory design, and much more.
https://peterdsharpe.github.io/AeroSandbox/
MIT License
687 stars 111 forks source link

aerosandbox.geometry.wing.control_surface_area does not work #128

Closed Daniel-E-B closed 3 months ago

Daniel-E-B commented 3 months ago

Bug Description / Observed Behavior

Running vlm.airplane.wings[0].control_surface_area() on a wing with a control surface between two xsecs, The output is

TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_80195/2227526581.py in <module>
----> 1 vlm.airplane.wings[0].control_surface_area()

~/.local/lib/python3.8/site-packages/aerosandbox/geometry/wing.py in control_surface_area(self, by_name, type)
    825 
    826         for xsec, sect_area in zip(self.xsecs[:-1], sectional_areas):
--> 827             for control_surface in xsec.control_surfaces:
    828                 if (by_name is None) or (control_surface.name == by_name):
    829 

TypeError: 'ControlSurface' object is not iterable

My wing has a control surface: vlm.airplane.wings[0].xsecs[2].control_surfaces with xsecs[1] or [2] returns ControlSurface (name=aileron, symmetric=False, deflection=0.0, hinge_point=0.75)

but control_surfaces is not an iterable and can't be treated like an array here. Either that or I've made some stupid python mistake :).

Steps to Reproduce

I added control surfaces to the 01-Vortex Lattice Method wing.

Expected Behavior

Should print the area of the control surface

System Information

Other Information

peterdsharpe commented 3 months ago

Hi Daniel!

This looks like it's due to improper types when the asb.WingXSec instance was constructed.

When constructing a asb.WingXSec, the control_surfaces argument should be a list of asb.ControlSurface objects, rather than a single one. This is true even if only one control surface is present. The motivation here is to allow overlapping control surfaces (e.g., to make a flaperon or elevon).

Input types can be checked using the docstring of most classes, which are type-hinted:

In [1]: asb.WingXSec?
Init signature:
asb.WingXSec(
    xyz_le: Union[numpy.ndarray, List] = None,
    chord: float = 1.0,
    twist: float = 0.0,
    airfoil: aerosandbox.geometry.airfoil.airfoil.Airfoil = None,
    control_surfaces: Optional[List[ForwardRef('ControlSurface')]] = None,  # <<< control_surfaces type hint
    analysis_specific_options: Optional[Dict[type, Dict[str, Any]]] = None,
    **deprecated_kwargs,
)
Docstring:      Definition for a wing cross-section ("X-section").
Init docstring:
Defines a new wing cross-section.
...
Daniel-E-B commented 3 months ago

Got it, thanks!