Closed kurt-rhee closed 1 year ago
Just a small suggestion, it would be good to include a script that is runnable for someone else to debug. For example including all the imports in the beginning and a entry point to the script at the end. Not just the class.
Your lcs_polygon_flat
should not have only one point. That is an invalid Polygon and it causes the index out of range.
from compas.data import Data
from compas.geometry import *
import math
class Bay(Data):
"""
A bay is a collection of modules sharing the same torque tube. Note that trackers and bays in TRACE use a
right-handed cartesian coordinate system with +x pointing East, +y pointing North and +z pointing towards
the sky. Industry software such as pvlib and pvsyst use a left-handed coordinate system.
"""
def __init__(
self,
bay_id: str = 'example',
num_modules: int = 0,
azimuth: float = 0.0,
axis_tilt: float = 0.0,
rotation_angle: int = 0,
lcs: Frame = Frame([0, 0, 0], [1, 0, 0], [0, 1, 0]),
lcs_polygon_flat: Polygon = Polygon([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]])
):
"""
Args:
bay_id: unique identifier for tracker
num_modules: number of pv modules in this bay
azimuth: angle rotated about +z axis in a right-handed cartesian frame of reference
rotation_angle: angle rotated about the torque tube axis (+y local frame of reference)
lcs: local coordinate system frame of reference
lcs_polygon_flat: geometry object representative of the bay with zero degrees of rotation
wcs_polygon_rotated: geometry object representative of the bay with rotation in world coordinate system
"""
# --- save base information ---
super().__init__()
# --- calculations ---
# calculate transformation of world and local coordinate systems
to_wcs = Transformation.from_frame_to_frame(
Frame.worldXY(),
lcs
)
# calculate rotated polygon
rotation_about_y = Rotation.from_axis_and_angle(
[0, 1, 0],
math.radians(rotation_angle)
)
lcs_polygon_rotated = lcs_polygon_flat.transformed(rotation_about_y)
# load
self.bay_id = bay_id
self.num_modules = num_modules
self.azimuth = azimuth
self.axis_tilt = axis_tilt
self.rotation_angle = rotation_angle
self.lcs = lcs
self.lcs_polygon_flat = lcs_polygon_flat
self.wcs_polygon_rotated = lcs_polygon_rotated.transformed(to_wcs)
@property
def data(self):
return {
'bay_id': self.bay_id,
'num_modules': self.num_modules,
'azimuth': self.azimuth,
'axis_tilt': self.axis_tilt,
'rotation_angle': self.rotation_angle,
'lcs': self.lcs,
'lcs_polygon_flat': self.lcs_polygon_flat,
'wcs_polygon_rotated': self.wcs_polygon_rotated
}
@data.setter
def data(self, data):
self.bay_id = data['bay_id']
self.num_modules = data['num_modules']
self.azimuth = data['azimuth']
self.axis_tilt = data['axis_tilt']
self.rotation_angle = data['rotation_angle']
self.lcs = data['lcs']
self.lcs_polygon_flat = data['lcs_polygon_flat']
self.wcs_polygon_rotated = data['wcs_polygon_rotated']
if __name__ == "__main__":
b = Bay()
print(b.data)
# Serialization and Deserialize
b.to_json('test.json', pretty=True)
c = Bay.from_json('test.json')
print(c.data)
See if this is what you want. The json looks like this.
"axis_tilt": 0.0,
"azimuth": 0.0,
"bay_id": "example",
"lcs": {
"dtype": "compas.geometry/Frame",
"value": {
"point": [
0.0,
0.0,
0.0
],
"xaxis": [
1.0,
0.0,
0.0
],
"yaxis": [
0.0,
1.0,
0.0
]
}
},
"lcs_polygon_flat": {
"dtype": "compas.geometry/Polygon",
"value": {
"points": [
[
0.0,
0.0,
0.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
1.0,
0.0
],
[
0.0,
1.0,
0.0
]
]
}
},
"num_modules": 0,
"rotation_angle": 0,
"wcs_polygon_rotated": {
"dtype": "compas.geometry/Polygon",
"value": {
"points": [
[
0.0,
0.0,
0.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
1.0,
0.0
],
[
0.0,
1.0,
0.0
]
]
}
}
}
print out looks like this
{'bay_id': 'example', 'num_modules': 0, 'azimuth': 0.0, 'axis_tilt': 0.0, 'rotation_angle': 0, 'lcs': Frame(Point(0.000, 0.000, 0.000), Vector(1.000, 0.000, 0.000), Vector(0.000, 1.000, 0.000)), 'lcs_polygon_flat': Polygon([Point(0.000, 0.000, 0.000), Point(1.000, 0.000, 0.000), Point(1.000, 1.000, 0.000), Point(0.000, 1.000, 0.000)]), 'wcs_polygon_rotated': Polygon([Point(0.000, 0.000, 0.000), Point(1.000, 0.000, 0.000), Point(1.000, 1.000, 0.000), Point(0.000, 1.000, 0.000)])}
{'bay_id': 'example', 'num_modules': 0, 'azimuth': 0.0, 'axis_tilt': 0.0, 'rotation_angle': 0, 'lcs': Frame(Point(0.000, 0.000, 0.000), Vector(1.000, 0.000, 0.000), Vector(0.000, 1.000, 0.000)), 'lcs_polygon_flat': Polygon([Point(0.000, 0.000, 0.000), Point(1.000, 0.000, 0.000), Point(1.000, 1.000, 0.000), Point(0.000, 1.000, 0.000)]), 'wcs_polygon_rotated': Polygon([Point(0.000, 0.000, 0.000), Point(1.000, 0.000, 0.000), Point(1.000, 1.000, 0.000), Point(0.000, 1.000, 0.000)])}
Hello,
Thank you for your help. I am able to get this working on this minimal example, but it my larger script where bay objects are nested inside of tracker objects, tracker objects are nested inside block objects and block objects are nested inside of site objects I can't seem to get this to work.
Is there a limited amount of nested structures that compas will allow?
A couple more data points:
site.to_json('dom.json', pretty=True)
and then load via Site.from_json('dom.json')
then nested structures don't worksite
<dom.objects.site.Site object at 0x7fec73ec60a0>
test = Site.from_data(site.data)
test
<dom.objects.site.Site object at 0x7fec4ee87340>
test.blocks[0].trackers[0].bays[0].data
{'bay_id': 0, 'num_modules': 6.0, 'azimuth': 0.0, 'axis_tilt': 0.784329445275794, 'rotation_angle': 0, 'lcs': Frame(Point(1107102.183, 253520.619, 65.197), Vector(1.000, 0.000, 0.000), Vector(-0.000, 1.000, 0.014)), 'lcs_polygon_flat': Polygon([Point(-0.500, 0.000, 0.100), Point(0.500, 0.000, 0.100), Point(0.500, 8.161, 0.100), Point(-0.500, 8.161, 0.100)]), 'wcs_polygon_rotated': Polygon([Point(1107101.683, 253520.618, 65.297), Point(1107102.683, 253520.618, 65.297), Point(1107102.683, 253528.778, 65.409), Point(1107101.683, 253528.778, 65.409)])}
I upgraded to compas 1.1.7 and followed the 1.1.7 documentation and fixed all of this. Thank you for your help!
Describe the bug I am attempting to create custom classes of objects which are an extension of compas.geometry objects and then serialize them to json. These are basically a geometry object(s) and some meta data about the object. These object serialize to json when I call bay.to_json, but fail to validate and also fail to read from_json.
To Reproduce Steps to reproduce the behavior:
Expected behavior I would expect for the Bay.from_json(file_location) to create a bay object.
Screenshots![image](https://user-images.githubusercontent.com/33131958/194763823-c78bd9d2-8e62-4b37-8150-82838669088d.png)
Desktop (please complete the following information):
Additional context Add any other context about the problem here.