-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #127 from mhhwang1/126-tower-class-and-tests
Adding Tower Class and Tests
- Loading branch information
Showing
7 changed files
with
467 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
""" | ||
Tower Class | ||
""" | ||
|
||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
from opencsp.common.lib.geometry.Pxyz import Pxyz | ||
import opencsp.common.lib.render_control.RenderControlTower as rct | ||
from opencsp.common.lib.csp.RayTraceable import RayTraceable | ||
from opencsp.common.lib.render_control.RenderControlPointSeq import RenderControlPointSeq | ||
from opencsp.common.lib.render_control.RenderControlTower import RenderControlTower | ||
from opencsp.common.lib.render.View3d import View3d | ||
|
||
|
||
class Tower(RayTraceable): | ||
""" | ||
Tower representation. | ||
All parameter values are in meters using ENU (East, North, Up) | ||
coordinate system. Values are relative to the field coordinates. | ||
Parameters: | ||
----------- | ||
name : str | ||
The name of this Tower. Used for special styles given in the draw method. | ||
origin : Pxyz | ||
The center of Tower. All other points in the tower are relative to this value. | ||
parts : list[str] | ||
The parts that build the Tower. Includes walls (top, northface, southface, bottom), and optionl target. | ||
height : float | ||
The height of Tower. Currently set for NSTTF Tower height of 61 m. | ||
east : float | ||
The East wall of the Tower. Currently set for 8.8 m. TODO, MHH find dimensions of tower (in particular width) | ||
west : float | ||
The West wall of the Tower. Currently set for 8.8 m. | ||
south : float | ||
The South wall of the Tower. Currently set for 8.8 m. | ||
north : float | ||
The North wall of the Tower. Currently set for 8.8 m. | ||
x_aim : float | ||
The x component of the target in relation to the Tower origin. | ||
y_aim : float | ||
The y component of the target in relation to the Tower origin. | ||
z_aim : float | ||
The z component of the target in relation to the Tower origin. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
name: str, | ||
origin: Pxyz, | ||
parts: list[str] = ["whole tower"], | ||
height: float = 100, | ||
east: float = 8.8, | ||
west: float = -8.8, | ||
south: float = -8.8, | ||
north: float = 8.8, | ||
x_aim: float = 0, | ||
y_aim: float = 8.8, | ||
z_aim: float = 100, | ||
): | ||
|
||
# parameters used for control tower at NSTTF | ||
# tower_control= Tower(name='Sandia NSTTF Control Tower', | ||
# origin = np.array([0,0,0]), | ||
# height=25, | ||
# east = 8.8, | ||
# west = -8.8, | ||
# south = 284, | ||
# north = 300) | ||
"""Create a new Tower instance. | ||
Parameters: | ||
----------- | ||
name The name of this Tower. Used for special styles given in the draw method. | ||
origin The center of Tower, as a three vector xyz coordinate. | ||
all measurements in meters using ENU coordinate system. | ||
""" | ||
super(Tower, self).__init__() | ||
self.name = name | ||
self.origin = origin | ||
self.parts = parts | ||
self.height = height | ||
self.east = east | ||
self.west = west | ||
self.south = south | ||
self.north = north | ||
self.x_aim = x_aim | ||
self.y_aim = y_aim | ||
self.z_aim = z_aim | ||
self.target_loc = Pxyz([x_aim, y_aim, z_aim]) | ||
|
||
# Tower faces, top, and bottom | ||
self.top = [ | ||
[self.east, self.north, self.height], | ||
[self.west, self.north, self.height], | ||
[self.west, self.south, self.height], | ||
[self.east, self.south, self.height], | ||
] | ||
|
||
self.northface = [ | ||
[self.east, self.north, self.height], | ||
[self.west, self.north, self.height], | ||
[self.west, self.north, 0], | ||
[self.east, self.north, 0], | ||
] | ||
""" | ||
The top-left, top-right, bottom-right, bottom-left corners of the Tower, | ||
as viewed when standing north of the tower and facing south. | ||
""" | ||
|
||
self.southface = [ | ||
[self.east, self.south, self.height], | ||
[self.west, self.south, self.height], | ||
[self.west, self.south, 0], | ||
[self.east, self.south, 0], | ||
] | ||
""" | ||
The top-left, top-right, bottom-right, bottom-left corners of the Tower, | ||
as viewed when standing south of the tower and facing north. | ||
""" | ||
|
||
self.bottom = [ | ||
[self.east, self.north, 0], | ||
[self.west, self.north, 0], | ||
[self.west, self.south, 0], | ||
[self.east, self.south, 0], | ||
] | ||
|
||
self.point = [self.x_aim, self.y_aim, self.z_aim] | ||
""" | ||
The target location given the x, y, and z components. | ||
""" | ||
|
||
def walls(self): | ||
"""Returns the list of walls as top, north, south, and bottom.""" | ||
# Assumes that Tower coordinates have been set, and the walls have been set. | ||
# # Later we can add a more meaningful check for this. | ||
return [self.top, self.northface, self.southface, self.bottom] | ||
|
||
# RENDERING | ||
|
||
def draw(self, view: View3d, tower_style: RenderControlTower) -> None: | ||
# Assumes that heliostat configuration has already been set. | ||
|
||
tower_style = tower_style.style(self.name) | ||
|
||
# Whole tower | ||
if 'whole tower' in self.parts: | ||
self.parts += ['top', 'northface', 'southface', 'bottom', 'northface'] | ||
|
||
# Top of tower | ||
if "top" in self.parts: | ||
view.draw_xyz_list(self.top, close=True, style=tower_style.wire_frame) | ||
|
||
# Northface of tower | ||
if "northface" in self.parts: | ||
view.draw_xyz_list(self.northface, close=True, style=tower_style.wire_frame) | ||
|
||
# Southface of tower | ||
if "southface" in self.parts: | ||
view.draw_xyz_list(self.southface, close=True, style=tower_style.wire_frame) | ||
|
||
# Bottom of tower | ||
if "bottom" in self.parts: | ||
view.draw_xyz_list(self.bottom, close=True, style=tower_style.wire_frame) | ||
|
||
# target on northface of tower | ||
if "target" in self.parts: | ||
view.draw_xyz(self.point, style=tower_style.target) | ||
|
||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import opencsp.common.lib.render_control.RenderControlPointSeq as rcps | ||
import opencsp.common.lib.render_control.RenderControlText as rctxt | ||
from opencsp.common.lib.render_control.RenderControlPointSeq import RenderControlPointSeq | ||
|
||
|
||
class RenderControlTower: | ||
""" | ||
Render control for towers. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
centroid=False, | ||
draw_name=False, | ||
name_style=None, | ||
draw_outline=True, | ||
point_styles: RenderControlPointSeq = None, | ||
wire_frame: RenderControlPointSeq = None, | ||
target: RenderControlPointSeq = None, | ||
) -> None: | ||
""" | ||
Controls for rendering a tower. | ||
Parameters | ||
---------- | ||
centroid : bool, optional | ||
If True, centroid will be drawn on graph as origin of tower. Default is False. | ||
draw_name : bool, optional | ||
If True then the name will be drawn on graph. Default is False. | ||
name_style : None | str | ||
If draw_name = True, then styles name using RenderControlText. By default from RenderControlText, color 'black'. | ||
draw_outline : bool | ||
Draws outline of Tower using wire_frame style. Default is True. | ||
point_styles : RenderControlPointSeq | ||
Draws target as a point on the Tower. | ||
wire_frame : RenderControlPointSeq | ||
Outline style of Tower, that draws walls edges. Default is RenderControlSeq outline, color 'black', linewidth '1'. | ||
target : RenderControlPointSeq | ||
If target, draws a point on Tower. Default color is 'red', with shape 'x', markersize '6'. | ||
""" | ||
|
||
# default values | ||
if name_style is None: | ||
namestyle = rctxt.default(color='k') | ||
if point_styles is None: | ||
point_styles = rcps.marker() | ||
if wire_frame is None: | ||
wire_frame = rcps.outline() | ||
if target is None: | ||
target = rcps.marker(marker='x', color='r', markersize=6) | ||
|
||
super(RenderControlTower, self).__init__() | ||
|
||
self.centroid = centroid | ||
self.draw_name = draw_name | ||
self.name_style = name_style | ||
self.draw_outline = draw_outline | ||
self.point_styles = point_styles | ||
self.wire_frame = wire_frame | ||
self.target = target | ||
|
||
def style(self, any): | ||
""" "style" is a method commonly used by RenderControlEnsemble. | ||
We add this method here so that RenderControlHeliostat can be used similarly to RenderControlEnsemble.""" | ||
return self | ||
|
||
# Common Configurations | ||
|
||
|
||
def normal_tower(): | ||
# Overall tower outline only. | ||
return RenderControlTower() | ||
|
||
|
||
def no_target(): | ||
# tower outline with no target. | ||
return RenderControlTower(wire_frame=rcps.outline(color='g'), target=False) |
Binary file added
BIN
+1.05 MB
opencsp/common/lib/test/data/input/TestTowerOutput/tto001_Single_Tower_3d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions
16
opencsp/common/lib/test/data/input/TestTowerOutput/tto001_Single_Tower_3d.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Metadata: | ||
Figure number: 1 | ||
Name: tto001_Single Tower | ||
Title: Single Tower | ||
Code tag: TestTowerOutput.test_single_tower() | ||
View spec: 3d | ||
|
||
Title: | ||
Single Tower | ||
|
||
Caption: | ||
A single Sandia NSTTF tower. | ||
|
||
Comments: | ||
Demonstration of single 3d tower drawing. | ||
|
Binary file added
BIN
+1.19 MB
opencsp/common/lib/test/data/input/TestTowerOutput/tto002_Multiple_Towers_3d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions
18
opencsp/common/lib/test/data/input/TestTowerOutput/tto002_Multiple_Towers_3d.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Metadata: | ||
Figure number: 1 | ||
Name: tto002_Multiple Towers | ||
Title: Multiple Towers | ||
Code tag: TestTowerOutput.test_multiple_towers() | ||
View spec: 3d | ||
|
||
Title: | ||
Multiple Towers | ||
|
||
Caption: | ||
Sandia NSTTF reciever and control tower. | ||
|
||
Comments: | ||
Demonstration of single 3d tower drawing. | ||
Black tower is NSTTF receiver tower. | ||
Green tower is NSTTF control tower. | ||
|
Oops, something went wrong.