airfoildatabase generation for machupX

155 views
Skip to first unread message

Marco

unread,
Aug 14, 2020, 11:00:28 AM8/14/20
to MachUp Forum
I unfortunately seem unable to figure out how to make the correct setting files and python calls to make an airfoildatabase for machypX with xfoil, from a set of custom airfoils.
Could you possible help me with a bit of a walkthrough?

Some explanation of the different 'options' to learn this procedure from (folders example, test and zach) could be helpful in my understanding.

From what I tried so far:
I cannot find out how to adapt zach's folder into accepting my custom airfoils (it only seems to do NACA foil?)
I can adapt file examples/ideal_input.json but the I dont know how to use this file to generate.database
If I take test/test.py and uncomment airfoil.generate_database and comment out all the airfoil.import_database then things start to run but for some reason it wants to find my airfoils chord line and although it's initial chord calculation seems ok, the iteration diverges and breaks the python run. Anyway it does not reach a point where it starts to run xfoil.

I hope you can help.
thanks, marco

Cory

unread,
Aug 17, 2020, 2:10:32 PM8/17/20
to MachUp Forum
Hi Marco

Thanks for your post. You've made me realize I never created any examples for AirfoilDatabase and left the root directory poorly organized. I'm working on fixing that and should have the change on Github by tomorrow.

That's interesting that the camber line finder diverges. Maybe I should add some relaxation to that one. But if you supply your own points, it does need to figure out the geometry of the camber line since flap deflections are defined relative to the camber line. If you wouldn't mind, sharing your geometry input here would help me troubleshoot that.

Have you read through the documentation at https://airfoildatabase.readthedocs.io/en/latest/? I'll work on a more clear walk-through. Basically what you need to do is write a Python script that initializes the Airfoil() class and uses that to generate and export a database. You then reference that database file in the airfoil input to MachUpX.

Thanks

Cory

Marco

unread,
Aug 18, 2020, 7:30:37 AM8/18/20
to machup...@googlegroups.com
Hello Cory,

Calculating camber line...
Camber error: 0.034154810302669626
Camber error: 0.3962466375815222
Camber error: 0.30391320751990486
Camber error: 0.2506046916058189
/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/airfoil.py:531: RuntimeWarning: divide by zero encountered in double_scalars
  s2
= s1-d1*(s0-s1)/(d0-d1)
Camber error: nan
Leading edge: [ 0.05187966 -0.03781971]
Trailing edge: [1. 0.]

Traceback (most recent call last):
 
File "my_airfoil_generator.py", line 21, in <module>
    airfoil
= adb.Airfoil("MMXX1500cTE4", airfoil_input, verbose=True)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/airfoil.py", line 44, in __init__
   
self._initialize_geometry()
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/airfoil.py", line 192, in _initialize_geometry
   
self._calc_geometry_from_points()
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/airfoil.py", line 430, in _calc_geometry_from_points
   
self._camber_line = interp.UnivariateSpline(camber_points[:,0], camber_points[:,1], k=5, s=1e-10)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/scipy/interpolate/fitpack2.py", line 173, in __init__
    check_finite
)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/scipy/interpolate/fitpack2.py", line 197, in validate_input
   
raise ValueError("x must be increasing if s > 0")
ValueError: x must be increasing if s > 0

Above is the console output when I tried making an airfoildatabase for my custom foil.
As you can see the initial camber error looks acceptable to me with 0.03415...
I would not mind sending the offending airfoil file directly to you.

CustomAirfoil_CamberLineEstimate_Result.jpeg


marco

Cory

unread,
Aug 18, 2020, 11:15:21 AM8/18/20
to MachUp Forum
Very strange. That's not an unusual airfoil at all, so I'm surprised it's failing. Go ahead and email me your geometry file and I'll look into it.

Thanks

Cory

Marco

unread,
Aug 18, 2020, 1:53:34 PM8/18/20
to MachUp Forum
I beleive I've send you a private email with attachment. I've never bevore done that through the google groups interface, so please give a received confirmation :-)

Cory

unread,
Aug 18, 2020, 3:00:01 PM8/18/20
to MachUp Forum
Got it! I didn't know one could do that. Good to know though. I'll let you know what I figure out.

Thanks

Cory

Cory

unread,
Aug 24, 2020, 7:58:16 PM8/24/20
to MachUp Forum
Hi Marco

I managed to fix the issue with the airfoil outline points you sent me, along with a few other related issues. Thanks again for bringing this up.

With the fixes, you'll need to change a couple things on your end (beyond installing the new version). For one, the nature of your airfoil geometry makes the camber line solver want to diverge (as you saw). To combat this, you'll want to set the "camber_relaxation" argument when you initialize your airfoil class. I got good results with this set around 0.2-0.5. Play with it a bit and see what produces a satisfactory geometry.

The other thing you'll need to do is alter your input points slightly. The way you have them defined right now, the trailing edge closes to a blunt point (i.e. almost square). AirfoilDatabase does not like this and I haven't figured out a clean way to handle that within the software. To remedy this, I took the first and last points and changed the y-value of each to be the same as the neighboring points. This made the airfoil have an open trailing edge with basically the same geometry. You could also solve this by making your points taper more gradually to a point, but that seems more difficult to me. Either way, you want to get rid of abrupt changes in the airfoil outline.

Give it a run and let me know how it goes. Again, you'll need to play with the relaxation parameter to see what works well. If you have any issues, let me know!

Thanks

Cory

Marco

unread,
Aug 25, 2020, 6:11:58 AM8/25/20
to MachUp Forum
Hi Cory,

I installed the testing-dev branch and the relaxation fix works for generating an airfoil database.
Thanks! push to master got my approval :-)
I did however subsequently got a fail at generating the polynomial fits (singular matrix error), but as MachupX can work directly with the database I was not planning on using the polyfits anyway.

Having an open trailing edge airfoil (instead of the blunt closed TE) was actually my original airfoil. As I believe xfoil requires an open TE if the TE is not sharp.
I've also read somewhere that xfoil uses different routines for sharp TE vs open TE and that the open TE routines behave nicer, thus even if your actual airfoil TE is pointed, for xfoil it is supposed to be better to introduce a tiny TE gap.
However, I had closed off the TE because of the following instructions for MachUpX;

geometry : dict, optional
Describes the geometry of the airfoil.
<snip>
The trailing edge should be sealed and points should be listed starting at the trailing edge.



Cory

unread,
Aug 25, 2020, 11:18:42 AM8/25/20
to MachUp Forum
Hi Marco

Glad it's working for you! I'll get that changed in the documentation. I wrote that before I was familiar with Xfoil.

Thanks

Cory

Marco

unread,
Aug 27, 2020, 3:30:08 AM8/27/20
to machup...@googlegroups.com
Hello Cory,

I had another airfoil that did not want to pass the airfoildb making.
the iteration did not want to converge further than 1.80701....e-10
I had to change the iteration code to
while camber_error > 2e-10:
for it to pass.

I tossed the offending foil to your email if you want to have a look,
perhaps the camber_error needs to be a value the user can set instead of it being hardcoded?

marco

Cory

unread,
Aug 27, 2020, 1:26:48 PM8/27/20
to MachUp Forum
Marco

Thanks for sending me that. I think having that as an option is a great idea. I'll get that added in.

Thanks

Cory

Marco

unread,
Aug 28, 2020, 11:10:18 AM8/28/20
to MachUp Forum
well i thought the having the airfoil database would let me run MachUpX on my airplane, but it seems that MachUpX does not directly use the database itself, but rather always wants to polyfit the data in the database? Because I tried and running MachUpX and it starts working (100%CPU usage) but it never gets anywhere.

So I uncommented
#    # Alternatively, you can have it automatically detect the order of fit that would be best for each
    airfoil.generate_polynomial_fit(CL_degrees="auto", CD_degrees="auto", Cm_degrees="auto", max_order=6)
#
#    # Export fits
    airfoil.export_polynomial_fits(filename="MMXX1500cTE4_polynomials.json")

To make the polyfits, but that errors with the following output:
Database generation complete.
Convergent results obtained from Xfoil for 97.17% of the design space.
Generating Polynomial Fits for airfoil MMXX1500cTE4
Performing CL curve fit
Determining the orthogonal p functions    ----------      0.000%    ETR = -:--:--.------/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/poly_fits.py:759: RuntimeWarning: invalid value encountered in double_scalars
  gamma
= np.dot(pj, temp) / np.dot(pj, pj)
Determining the orthogonal p functions    ΞΞΞΞΞΞΞΞΞΞ    100.000%    Run Time 0:36:35.097180
/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/poly_fits.py:771: RuntimeWarning: invalid value encountered in double_scalars
  ajhat
= np.dot(pj, y) / pjdot
Sorting the p functions by effectivenss    ΞΞΞΞΞΞΞΞΞΞ    100.000%    Run Time 0:01:48.960899
Determining number of p functions to use    ----------      0.000%    ETR = -:--:--.------Traceback (most recent call last):
 
File "MMXX1500cTE4_generate_foildb.py", line 89, in <module>
    airfoil
.generate_polynomial_fit(CL_degrees="auto", CD_degrees="auto", Cm_degrees="auto", max_order=6)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/airfoil.py", line 2310, in generate_polynomial_fit
   
self._CL_poly_coefs, self._CL_degrees, self._CLfit_R2 = autoPolyFit(self._data[:,:self._num_dofs], self._data[:, self._num_dofs], **CL_kwargs)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/airfoil_db/poly_fits.py", line 790, in autoPolyFit
    ahat
= np.matmul(np.matmul(np.linalg.inv(np.matmul(Phat.transpose(), Phat)), Phat.transpose()), y)
 
File "<__array_function__ internals>", line 6, in inv
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py", line 546, in inv
    ainv
= _umath_linalg.inv(a, signature=signature, extobj=extobj)
 
File "/home/marco/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py", line 88, in _raise_linalgerror_singular
   
raise LinAlgError("Singular matrix")
numpy
.linalg.LinAlgError: Singular matrix


Cory

unread,
Aug 28, 2020, 11:23:08 AM8/28/20
to MachUp Forum
Hi Marco

That is strange. MachUpX will use the data you give it. If you give it a database file, it will use that database directly. It will only use the poly_fit type if that is what you give it. Where exactly is it getting hung up?

Thanks

Cory

Marco

unread,
Aug 28, 2020, 1:18:41 PM8/28/20
to machup...@googlegroups.com
running it the MachUpX way it only gives the FutureWarning: Passing (type, 1) message and then a blinky cursor (while CPU goes to 100), I had it running for about 20 min when I stopped the program, as just loading the airplane should not take that long.

If I do  python -m machupX NLD_MMXX_input.json then it gives the machup splash screen and Loading aircraft and scene... message,.. same thing, let it go for 20 min,.. but nope.

So no meaning full error message at all.

Can I email you my airplane working directory for you to try?

marco
Message has been deleted

Marco

unread,
Aug 28, 2020, 1:39:24 PM8/28/20
to MachUp Forum
Thanks for putting the time in this for me.
And if you think this crazy airplane idea will never work please do tell (you are the first I show the idea to)

Cory

unread,
Aug 28, 2020, 2:00:51 PM8/28/20
to MachUp Forum
Hi Marco

I've got your file running and it does the same thing for me, runs forever with no output. It appears it's taking awhile to find the camber line (our old nemesis ;) ) of each airfoil you've defined. I'm going to work on speeding that up and making it more reliable. In the meantime, I have a couple of thoughts:

1. If you're not going to use MachUpX to export 3D geometries (stl, etc), then you don't need to give the outline points for each airfoil. For aerodynamics, MachUpX only needs the database file. Doing so will let you bypass the above issue so you can still perform aerodynamic analysis while I'm working on this.
2. I implemented (1) and got an error that came from "trailing_flap_deflection", "trailing_flap_fraction", and "Mach" all being identically zero at every point in the database. I looked at your database generator scripts and you've incorrectly specified those degrees of freedom. If you want a degree of freedom to be a constant value, you replace the dictionary with just a single float (see line 48 of MUXF/MMXX50spanTE4_generate_foildb.py). Otherwise, AirfoilDatabase will think it's a degree of freedom when it's really not, since it's a constant. I'll work on clarifying that in the docs.
3. In your airplane geometry file, I see you've defined twist, sweep, dihedral, twist, and chord at a set of points. However, a lot of these are redundant, since it's either all zero or the value is the same for more than two points in a row. This will really slow down MachUpX, since it doesn't check for and resolve such redundancy. I'd recommend removing the redundant points. I've attached your geometry file with those points removed. Doing this made it load much faster for me.
4. You've listed "control_surface" in the airplane geometry file but have not specified any parameters, which means MachUpX will assume there is a control surface along the entire span of the wing with a 25% chord fraction. If you don't want a control surface, you'll need to remove that key entirely.

It's an interesting looking aircraft, from what I can tell without knowing the section geometries. Reminds me of a couple we've been working on in our lab lately.

Thanks

Cory
Message has been deleted

Marco

unread,
Aug 28, 2020, 4:04:41 PM8/28/20
to MachUp Forum

2. I implemented (1) and got an error that came from "trailing_flap_deflection", "trailing_flap_fraction", and "Mach" all being identically zero at every point in the database. I looked at your database generator scripts and you've incorrectly specified those degrees of freedom. If you want a degree of freedom to be a constant value, you replace the dictionary with just a single float (see line 48 of MUXF/MMXX50spanTE4_generate_foildb.py). Otherwise, AirfoilDatabase will think it's a degree of freedom when it's really not, since it's a constant. I'll work on clarifying that in the docs.


 Yes, I was unsure about how to correctly use a constant for those, because I was unsure about the then missing "index" value. Thinking that a range of [0,0] step 1 would probably behave the same as a single constant.

Cory

unread,
Aug 28, 2020, 4:11:56 PM8/28/20
to MachUp Forum
That looks sweet! I love that you're working proverse yaw into it. Will it just have weight-shift control like a hangglider?

The difference between the two approaches is that if you give it a range of [0,0] and a step of 1, it will think that that variable needs to be stored in the database. This will give a column of all the same values in the database. When this gets read back in, it confuses the algorithm because it expects to be able to interpolate in that variable but can't. With the other approach, just giving a float, that variable will not be stored in the database, as it is unnecessary.

Message has been deleted

Cory

unread,
Aug 31, 2020, 11:10:29 AM8/31/20
to MachUp Forum
I see. That sounds really cool! This is similar to a project two members of our lab have been engaged in recently. I'll message them and ask them to chime in on this thread or respond to you off list. They would have better feedback than I.

On Friday, August 28, 2020 at 3:05:43 PM UTC-6 Marco wrote:
I've heard that weight shift becomes problematic when span becomes large (the reason that current hangliders are about at their maximum span)  and I did not want the pilot to be hanging as far underneath the wing as hangliders do.
Because I use the bell shaped liftdistribution, there is a point near 93%span that always needs to stay at an AoA of zero (with a symetric airfoil).
I'll have a speed/CL lever (similar to setting the flaps on a normal plane) that sets the AoA of the 0to40%span section, while keeping that zero-AoA-rib at zero.
So to get full controll I'll then only have to tie the 80%span rib to the steering wheel to simultaneously set the 2 linear twists of the 40-80%span and 80-100%span sections.
Resulting in full controll while maintaining the sin^3 lift over the whole speed range. Atleast... thats the idea, but I dont have a education in this field, so maybe i'm just thinking bonkers.
So, a spratt controllwing (nobody does that), variable wingtwist (nobody does that), BSLD (nobody does that), footlaunching (almost nobody does that), prone pilot with a 'backpack' wing (well you get the idea).... I'm probably setting myself up for a short flight to death :-)

zachary.s.montgomery

unread,
Aug 31, 2020, 1:08:26 PM8/31/20
to MachUp Forum
Hello Marco. So I'm working on something very similar with regards to the aerodynamics and control aspect. I'm not planning on actually building anything. You said that at approximately 93% down the semispan the aoa needs to be 0 with a symmetric airfoil. Does this mean at this point the lift is zero? and is there negative lift outboard of this point? If I understand your mechanism correctly, each semispan has 3 sections that you can rotate. 0-40% controlled by your speed/CL lever, and two sections 40-80% and 80-100% that are controlled by the steering wheel for roll control, like a two step aileron. And you are using a combination of chord distribution and the speed/CL lever to maintain the bell shaped lift distribution so that your two step aileron always produces proverse yaw. Is this correct? You aren't doing any differential deflection of the ailerons to help with the yaw are you?
Message has been deleted

Zach

unread,
Aug 31, 2020, 5:00:55 PM8/31/20
to MachUp Forum
I'm not sure what the Spratt controlwing principle is.
You can still call them elevons even when they use the full chord. They still perform the same function.
I think your design could work, though it may be tricky for the pilot to know how much to push/pull the stick to give the desired amount of proverse yaw.

My study looked into the spanwise size and location of ailerons that would produce a desired roll-yaw coupling if the wing was using a bell shaped lift distribution.

As far as how to generate the bell shaped lift distribution there are two things you can alter: chord and twist distributions. For any given chord distribution, there is a twist distribution that will give the bell shaped lift distribution, but it is dependent on a desired CL. Instead, you could use no twist distribution and only the chord distribution to generate the bell shaped lift distribution which would mean the wing would always generate the bell shaped lift regardless of angle of attack. Although, this chord distribution would probably be difficult to actually build.

On Monday, August 31, 2020 at 1:14:13 PM UTC-6 Marco wrote:
Hi Zach
I for sure wish to build one for myself, and am aiming to best an ATOS rigid wing.
If I succeed in both I was dreaming to start a tiny company and sell them.
So a request to Cory,..
plz keep all data under tight lock with a stamp of 'top secret', I'd hate to see a Chinese version before I got mine ready.
and for Zach,..
as you say you have no intention of building one, then I don't mind showing you the design secrets and especially not if I can benefit from the knowledge of a real airplane designer!
Are you also studying the Spratt controllwing principle, or are you looking at this idea from a fixed wing perspective?

Can one still speak of an aileron/elevon when the whole wing is used as a control area?
The data that Cory has was my first guestimate for the chordlengths and today I am working on a new chord distribution that should fit the sin^3 even better.

You describe the mechanism correct.
The 0-40%semispan section will be rigid and it's AoA is set by the speed/CL lever, the pilot sets this appropriately for the next flight segment and can then use both hands on the controllwheel.
Push/Pull the controllwheel will twist both left and right wing 80%semispan ribs up or down to dial in the whole sin^3 distribution (and can also be used to temporarily give more or less lift for short duration glide angle control). The rest of the ribs in the 40-80% section will follow the lead of the 80%rib and that section will thus take on a certain linear twist towards the center 0-40% section.
Turning the wheel gives roll control by twisting the left wing 80%rib up while the right wing one goes down the same amount (and again the rest of the 40-80% section ribs follow). The mechanism I have in mind would be adaptable to do differential If it turns out that would be needed.
The 80-100%semispan section will work similar, keeping the 93%rib at zero twist and having that section's TE spar follow the 80%rib will give me another linear twist in that section and indeed gives negative twist (washin) in the 93 to 100% part. However It should not give negative lift as washin amount is less than the glide angle.


Reply all
Reply to author
Forward
Message has been deleted
0 new messages