Skip to content

Commit

Permalink
improve glider_2d import (ods)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiaselhans committed Feb 10, 2015
1 parent 9b5dab6 commit fc9336b
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 41 deletions.
1 change: 1 addition & 0 deletions openglider/glider/ballooning.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ def __init__(self, upper=None, lower=None):
def __json__(self):
return {"upper": [p.tolist() for p in self.upper_spline.controlpoints],
"lower": [p.tolist() for p in self.lower_spline.controlpoints]}

@property
def points(self):
upper = list(self.upper_spline.get_sequence())
Expand Down
52 changes: 33 additions & 19 deletions openglider/glider/glider_2d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class Glider2D(object):
"""
A parametric (2D) Glider object used for gui input
"""
def __init__(self, front, back, cell_dist, cell_num, arc,
aoa, profiles, lineset,
def __init__(self, front, back, cell_dist, cell_num,
arc, aoa, profiles, profile_merge_curve,
balloonings, ballooning_merge_curve, lineset,
speed, glide):
self.front = front
self.back = back
Expand All @@ -32,6 +33,9 @@ def __init__(self, front, back, cell_dist, cell_num, arc,
self.arc = arc
self.aoa = aoa
self.profiles = profiles or []
self.profile_merge_curve = profile_merge_curve
self.balloonings = balloonings or []
self.ballooning_merge_curve = ballooning_merge_curve
self.lineset = lineset or LineSet2D([], [])
self.speed = speed
self.glide = glide
Expand All @@ -53,6 +57,9 @@ def __json__(self):
"arc": self.arc,
"aoa": self.aoa,
"profiles": self.profiles,
"profile_merge_curve": self.profile_merge_curve,
"balloonings": self.balloonings,
"ballooning_merge_curve": self.ballooning_merge_curve,
"lineset": self.lineset,
"speed": self.speed,
"glide": self.glide
Expand Down Expand Up @@ -139,6 +146,12 @@ def set_span(attribute):
for attr in 'back', 'front', 'cell_dist', 'aoa':
set_span(attr)

arc_pos = self.get_arc_positions()
arc_length = arc_pos.get_length() + arc_pos[0][0] # add center cell
factor = span/arc_length
self.arc.controlpoints = [[p[0]*factor, p[1]*factor]
for p in self.arc.controlpoints]

@property
def cell_dist_controlpoints(self):
return self.cell_dist.controlpoints[1:-1]
Expand Down Expand Up @@ -229,6 +242,10 @@ def mirror_x(polyline):
profile_dist = BezierCurve.fit([[i, i] for i in range(len(profiles))],
numpoints=numpoints)

balloonings = [rib.ballooning for rib in glider.ribs]
ballooning_dist = BezierCurve.fit([[i, i] for i in range(len(balloonings))],
numpoints=numpoints)

# TODO: lineset

return cls(front=front_bezier,
Expand All @@ -238,6 +255,9 @@ def mirror_x(polyline):
arc=arc_bezier,
aoa=aoa_bezier,
profiles=profiles,
profile_merge_curve=profile_dist,
balloonings=balloonings,
ballooning_merge_curve=ballooning_dist,
glide=glider.glide,
speed=10,
lineset=LineSet2D([]))
Expand All @@ -248,31 +268,23 @@ def get_glider_3d(self, glider=None, num=50):
ribs = []
cells = []

# TODO airfoil, ballooning-------
airfoil = self.profiles[0]
aoa_int = numpy.deg2rad(13.)
#--------------------------------------

span = self.front.controlpoints[-1][0]
self.set_span(span)

x_values = [rib_no[0] for rib_no in self.cell_dist_interpolation]
front_int = self.front.interpolate_3d(num=num)
back_int = self.back.interpolate_3d(num=num)
profile_merge_curve = self.profile_merge_curve.interpolate_3d(num=num)
ballooning_merge_curve = self.ballooning_merge_curve.interpolate_3d(num=num)

_arc_pos = self.get_arc_positions(num=num)
_arc_scale_factor = x_values[-1]/_arc_pos.get_length()
_arc_pos.scale(_arc_scale_factor)
arc_pos = list(_arc_pos)
arc_pos = list(self.get_arc_positions(num=num))
#_arc_scale_factor = x_values[-1]/_arc_pos.get_length()
#_arc_pos.scale(_arc_scale_factor)
#arc_pos = list(_arc_pos)

arc_angles = self.get_arc_angles()

#aoa_cp = self.aoa.controlpoints
#aoa_x_factor = x_values[-1] / aoa_cp[-1][0]
#self.aoa.controlpoints = [[p[0] * aoa_x_factor, p[1]] for p in aoa_cp]

aoa_int = self.aoa.interpolate_3d(num=num)
#merge_curve_profile = self.profile_merge_curve.interpolate_3d(num=num)

if x_values[0] != 0.:
# adding the mid cell
Expand All @@ -284,25 +296,27 @@ def get_glider_3d(self, glider=None, num=50):
front = front_int(pos)
back = back_int(pos)
arc = arc_pos[rib_no]

ribs.append(Rib(
profile_2d=airfoil.copy(),
#profile_2d=self.merge_profile(merge_curve_profile(pos)),
profile_2d=self.merge_profile(profile_merge_curve(abs(pos))[1]),
ballooning=self.merge_ballooning(ballooning_merge_curve(abs(pos))[1]),
startpoint=numpy.array([-front[1], arc[0], arc[1]]),
chord=norm(front - back),
arcang=arc_angles[rib_no],
glide=self.glide,
aoa_absolute=aoa_int(pos)[1]
))
ribs[-1].aoa_relative = aoa_int(pos)[1]

for rib_no, rib in enumerate(ribs[1:]):
cell = Cell(ribs[rib_no], rib, [])
cell.panels = [Panel([-1, -1, 3, 0.012], [1, 1, 3, 0.012], rib_no)]
cells.append(cell)
glider.cells = cells

glider.close_rib()

glider.lineset = self.lineset.return_lineset(glider)
glider.lineset.calc_geo()
glider.lineset.calc_sag()

return glider
31 changes: 19 additions & 12 deletions openglider/glider/glider_2d/import_ods.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def import_ods_2d(cls, filename, numpoints=4):
for i in range(datasheet.nrows()):
data[datasheet.get_cell([i, 0]).value] = datasheet.get_cell([i, 1]).value

# All Lists
front = []
back = []
cell_distribution = []
Expand All @@ -42,19 +43,21 @@ def import_ods_2d(cls, filename, numpoints=4):
profile_merge = []
ballooning_merge = []

main = sheets[0]
x = y = z = span_last = alpha = 0.

for i in range(1, main.nrows()+1):
line = [main.get_cell([i, j]).value for j in range(main.ncols())]
y = z = span_last = alpha = 0.
main_sheet = sheets[0]
assert isinstance(main_sheet, ezodf.Sheet)
for i in range(1, main_sheet.nrows()+1):
line = [main_sheet.get_cell([i, j]).value for j in range(main_sheet.ncols())]
if not line[0]:
break # skip empty line
# Index, Choord, Span(x_2d), Front(y_2d=x_3d), d_alpha(next), aoa,
chord = line[1]
span = line[2]
x = line[3]
y += numpy.cos(alpha) * (span - span_last)
z -= numpy.sin(alpha) * (span - span_last)

chord = line[1] # Rib-Chord
span = line[2] # spanwise-length (flat)
x = line[3] # x-value -> front/back (ribwise)
y += numpy.cos(alpha) * (span - span_last) # y-value -> spanwise
z -= numpy.sin(alpha) * (span - span_last) # z-axis -> up/down
alpha += line[4] * numpy.pi / 180 # angle after the rib

aoa.append([span, line[5] * numpy.pi / 180])
arc.append([y, z])
Expand All @@ -67,7 +70,6 @@ def import_ods_2d(cls, filename, numpoints=4):

zrot = line[7] * numpy.pi / 180

alpha += line[4] * numpy.pi / 180 # angle after the rib
span_last = span

# rib_no, id, pos, force
Expand All @@ -78,7 +80,8 @@ def import_ods_2d(cls, filename, numpoints=4):
cell_no = (len(front)-1)*2 + has_center_cell

def symmetric_fit(data):
mirrored = [[-p[0], p[1]] for p in data[1:]][::-1] + data
not_from_center = data[0][0] == 0
mirrored = [[-p[0], p[1]] for p in data[not_from_center:]][::-1] + data
return SymmetricBezier.fit(mirrored, numpoints=numpoints)

start = (2 - has_center_cell) / cell_no
Expand All @@ -91,13 +94,17 @@ def symmetric_fit(data):
rib_distribution = BezierCurve.fit(rib_distribution, numpoints=numpoints+3)

attachment_points_lower = get_lower_aufhaengepunkte(data)

return cls(front=symmetric_fit(front),
back=symmetric_fit(back),
cell_dist=rib_distribution,
cell_num=cell_no,
arc=symmetric_fit(arc),
aoa=symmetric_fit(aoa),
profiles=profiles,
profile_merge_curve=symmetric_fit(profile_merge),
balloonings=balloonings,
ballooning_merge_curve=symmetric_fit(ballooning_merge),
lineset=tolist_lines(sheets[6], attachment_points_lower, attachment_points),
speed=data.get("SPEED", 0),
glide=data.get("GLEITZAHL", 10))
Expand Down
4 changes: 4 additions & 0 deletions openglider/vector/polyline.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def scale(self, x, y=None):
if y is None:
y = x
self.data *= [x, y]
return self


class PolyLine2D(PolyLine):
Expand Down Expand Up @@ -265,8 +266,11 @@ def mirror(self, p1, p2):
"""
Mirror against a line through p1 and p2
"""
p1 = numpy.array(p1)
p2 = numpy.array(p2)
normvector = normalize(numpy.array(p1-p2).dot([[0, -1], [1, 0]]))
self.data = [point - 2*normvector.dot(point-p1)*normvector for point in self.data]
return self

def rotate(self, angle, startpoint=None):
"""
Expand Down
12 changes: 7 additions & 5 deletions tests/test_glider_2d.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import unittest


from common import *
from openglider import jsonify
from openglider.glider import Glider2D
from openglider.glider.glider_2d import Glider2D


class GliderTestCase2D(TestCase):
Expand All @@ -12,13 +11,16 @@ def setUp(self):

def test_fit(self):
glider_3d = self.import_glider()
self.assertEqualGlider(glider_3d, self.glider2d.get_glider_3d(), precision=0)
self.assertEqualGlider2D(Glider2D.fit_glider_3d(glider_3d), self.glider2d)

#@unittest.skip('')
def test_create_glider(self):
glider = self.glider2d.get_glider_3d()
self.assertAlmostEqual(glider.span, self.glider2d.span)

def test_export(self):
exp = jsonify.dumps(self.glider2d)
imp = jsonify.loads(exp)['data']
self.assertEqualGlider2D(self.glider2d, imp)
self.assertEqualGlider2D(self.glider2d, imp)

if __name__ == '__main__':
unittest.main()
24 changes: 20 additions & 4 deletions tests/visual_test_bezier.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@

import random
import sys
import os
import unittest
import numpy
from openglider.vector import PolyLine

try:
import openglider
except ImportError:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
import openglider
from openglider.graphics import Graphics2D, Graphics, Line, Green, Red
from openglider.graphics import Graphics2D, Graphics, Line, Green, Red, Blue
import openglider.airfoil
from openglider.utils.bezier import BezierCurve, SymmetricBezier


class TestMarks(unittest.TestCase):
class TestBezier(unittest.TestCase):
def setUp(self):
self.curve = BezierCurve()
self.points = [[0., 0.], [0.5, 0.5], [1., 0.]]
self.curve = BezierCurve(self.points)
self.profile = openglider.airfoil.Profile2D.compute_naca(9012, numpoints=100)

def test_bezier_fit(self):
Expand Down Expand Up @@ -57,6 +58,21 @@ def test_symmetric_bezier_fit(self):
Line(lower._controlpoints)
])

def test_scale_bezier(self):
curve1 = self.curve.get_sequence()
factor = 1+random.random()
curve2 = PolyLine(curve1)
curve2.scale(factor)
curve3 = self.curve.copy()
curve3.controlpoints = [[p[0]*factor, -p[1]*factor] for p in curve3.controlpoints]
Graphics([
Line(curve1),
Red,
Line(curve3.get_sequence()),
Blue,
Line(curve2)
])


if __name__ == "__main__":
unittest.main(verbosity=2)
1 change: 0 additions & 1 deletion tests/visual_test_glider2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ def test_fit(self):

def test_show_glider(self):
glider3d = self.glider2d.get_glider_3d()
#print([rib.pos for rib in glider3d.ribs])
TestGlider.show_glider(glider3d)

0 comments on commit fc9336b

Please sign in to comment.