ubc-solar-physics 1.7.3__cp39-cp39-macosx_10_12_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. physics/__init__.py +14 -0
  2. physics/_version.py +16 -0
  3. physics/environment/__init__.py +15 -0
  4. physics/environment/environment.rs +2 -0
  5. physics/environment/gis/__init__.py +7 -0
  6. physics/environment/gis/base_gis.py +38 -0
  7. physics/environment/gis/gis.py +371 -0
  8. physics/environment/gis/gis.rs +113 -0
  9. physics/environment/gis.rs +1 -0
  10. physics/environment/meteorology/__init__.py +3 -0
  11. physics/environment/meteorology/base_meteorology.py +69 -0
  12. physics/environment/meteorology/clouded_meteorology.py +600 -0
  13. physics/environment/meteorology/irradiant_meteorology.py +107 -0
  14. physics/environment/meteorology/meteorology.rs +138 -0
  15. physics/environment/meteorology.rs +1 -0
  16. physics/environment.rs +2 -0
  17. physics/lib.rs +164 -0
  18. physics/models/__init__.py +13 -0
  19. physics/models/arrays/__init__.py +7 -0
  20. physics/models/arrays/arrays.rs +0 -0
  21. physics/models/arrays/base_array.py +6 -0
  22. physics/models/arrays/basic_array.py +39 -0
  23. physics/models/arrays.rs +1 -0
  24. physics/models/battery/__init__.py +18 -0
  25. physics/models/battery/base_battery.py +29 -0
  26. physics/models/battery/basic_battery.py +140 -0
  27. physics/models/battery/battery.rs +102 -0
  28. physics/models/battery/battery_config.py +107 -0
  29. physics/models/battery/battery_config.toml +6 -0
  30. physics/models/battery/battery_model.py +226 -0
  31. physics/models/battery/kalman_filter.py +223 -0
  32. physics/models/battery.rs +1 -0
  33. physics/models/constants.py +23 -0
  34. physics/models/lvs/__init__.py +7 -0
  35. physics/models/lvs/base_lvs.py +6 -0
  36. physics/models/lvs/basic_lvs.py +18 -0
  37. physics/models/lvs/lvs.rs +0 -0
  38. physics/models/lvs.rs +1 -0
  39. physics/models/motor/__init__.py +9 -0
  40. physics/models/motor/advanced_motor.py +196 -0
  41. physics/models/motor/base_motor.py +8 -0
  42. physics/models/motor/basic_motor.py +193 -0
  43. physics/models/motor/motor.rs +0 -0
  44. physics/models/motor.rs +1 -0
  45. physics/models/regen/__init__.py +7 -0
  46. physics/models/regen/base_regen.py +6 -0
  47. physics/models/regen/basic_regen.py +52 -0
  48. physics/models/regen/regen.rs +0 -0
  49. physics/models/regen.rs +1 -0
  50. physics/models.rs +5 -0
  51. physics_rs/__init__.pyi +111 -0
  52. physics_rs.cpython-39-darwin.so +0 -0
  53. ubc_solar_physics-1.7.3.dist-info/LICENSE +21 -0
  54. ubc_solar_physics-1.7.3.dist-info/METADATA +142 -0
  55. ubc_solar_physics-1.7.3.dist-info/RECORD +57 -0
  56. ubc_solar_physics-1.7.3.dist-info/WHEEL +5 -0
  57. ubc_solar_physics-1.7.3.dist-info/top_level.txt +2 -0
@@ -0,0 +1,193 @@
1
+ import math
2
+ import numpy as np
3
+ from numpy.typing import NDArray
4
+ from physics.models.motor.base_motor import BaseMotor
5
+ from physics.models.constants import ACCELERATION_G, AIR_DENSITY
6
+
7
+
8
+ class BasicMotor(BaseMotor):
9
+ def __init__(self, vehicle_mass, road_friction, tire_radius, vehicle_frontal_area, drag_coefficient):
10
+ super().__init__()
11
+
12
+ # Instantaneous voltage supplied by the battery to the motor controller
13
+ self.dc_v = 0
14
+
15
+ # Instantaneous current supplied by the battery to the motor controller
16
+ self.dc_i = 0
17
+
18
+ self.input_power = 0
19
+ self.vehicle_mass = vehicle_mass
20
+ self.acceleration_g = ACCELERATION_G
21
+ self.road_friction = road_friction
22
+ self.tire_radius = tire_radius
23
+
24
+ self.air_density = AIR_DENSITY
25
+ self.vehicle_frontal_area = vehicle_frontal_area
26
+ self.drag_coefficient = drag_coefficient
27
+
28
+ self.friction_force = (self.vehicle_mass * self.acceleration_g * self.road_friction)
29
+
30
+ self.e_mc = 0.98 # motor controller efficiency, subject to change
31
+ self.e_m = 0.9 # motor efficiency, subject to change
32
+
33
+ # print("torque experienced by motor: {} Nm".format(self.constant_torque))
34
+
35
+ @staticmethod
36
+ def calculate_motor_efficiency(motor_angular_speed, motor_output_energy, tick, *args, **kwargs):
37
+ """
38
+
39
+ Calculates a NumPy array of motor efficiency from NumPy array of operating angular speeds and NumPy array
40
+ of output power. Based on data obtained from NGM SC-M150 Datasheet and modelling done in MATLAB
41
+
42
+ r squared value: 0.873
43
+
44
+ :param np.ndarray motor_angular_speed: (float[N]) angular speed motor operates in rad/s
45
+ :param np.ndarray motor_output_energy: (float[N]) energy motor outputs to the wheel in J
46
+ :param float tick: length of 1 update cycle in seconds
47
+ :returns e_m: (float[N]) efficiency of the motor
48
+ :rtype: np.ndarray
49
+
50
+ """
51
+
52
+ # Power = Energy / Time
53
+ motor_output_power = motor_output_energy * tick
54
+ rads_rpm_conversion_factor = 30 / math.pi
55
+
56
+ revolutions_per_minute = motor_angular_speed * rads_rpm_conversion_factor
57
+
58
+ e_m = calculate_motor_efficiency(motor_output_power, revolutions_per_minute)
59
+
60
+ e_m[e_m < 0.7382] = 0.7382
61
+ e_m[e_m > 1] = 1
62
+
63
+ return e_m
64
+
65
+ @staticmethod
66
+ def calculate_motor_controller_efficiency(motor_angular_speed, motor_output_energy, tick):
67
+ """
68
+
69
+ Calculates a NumPy array of motor controller efficiency from NumPy array of operating angular speeds and
70
+ NumPy array of output power. Based on data obtained from the WaveSculptor Motor Controller Datasheet efficiency
71
+ curve for a 90 V DC Bus and modelling done in MATLAB.
72
+
73
+ r squared value: 0.7431
74
+
75
+ :param np.ndarray motor_angular_speed: (float[N]) angular speed motor operates in rad/s
76
+ :param np.ndarray motor_output_energy: (float[N]) energy motor outputs to the wheel in J
77
+ :param float tick: length of 1 update cycle in seconds
78
+ :returns e_mc (float[N]) efficiency of the motor controller
79
+ :rtype: np.ndarray
80
+
81
+ """
82
+
83
+ # Ignore nan warning. Set nan value to 0
84
+ np.seterr(divide='ignore', invalid='ignore')
85
+
86
+ # Power = Energy / Time
87
+ motor_output_power = motor_output_energy / tick
88
+
89
+ # Torque = Power / Angular Speed
90
+ motor_torque_array = np.nan_to_num(motor_output_power / motor_angular_speed)
91
+
92
+ np.seterr(divide='warn', invalid='warn')
93
+
94
+ e_mc = calculate_motor_controller_efficiency(motor_angular_speed, motor_torque_array)
95
+
96
+ e_mc[e_mc < 0.9] = 0.9
97
+ e_mc[e_mc > 1] = 1
98
+
99
+ return e_mc
100
+
101
+ def calculate_net_force(self,
102
+ required_speed_kmh: NDArray,
103
+ wind_speeds: NDArray,
104
+ gradients: NDArray
105
+ ) -> tuple[NDArray, NDArray]:
106
+ """
107
+ Calculate the net force on the car, and the required wheel angular velocity.
108
+ Currently, considers:
109
+ 1. Rolling resistance of the wheels on the road
110
+ 2. Drag force (wind + forward velocity)
111
+ 3. Acceleration force (a = F / m)
112
+ 4. Gravitational force (force to go uphill)
113
+
114
+ :return: net force in N, wheel angular velocity in rad/s
115
+ """
116
+ required_speed_ms = required_speed_kmh / 3.6
117
+
118
+ acceleration_ms2 = np.clip(np.gradient(required_speed_ms), a_min=0, a_max=None)
119
+ acceleration_force = acceleration_ms2 * self.vehicle_mass
120
+
121
+ required_angular_speed_rads = required_speed_ms / self.tire_radius
122
+
123
+ drag_forces = 0.5 * self.air_density * (
124
+ (required_speed_ms + wind_speeds) ** 2) * self.drag_coefficient * self.vehicle_frontal_area
125
+
126
+ angles = np.arctan(gradients)
127
+ g_forces = self.vehicle_mass * self.acceleration_g * np.sin(angles)
128
+
129
+ road_friction_array = self.road_friction * self.vehicle_mass * self.acceleration_g * np.cos(angles)
130
+
131
+ net_force = road_friction_array + drag_forces + g_forces + acceleration_force
132
+
133
+ return net_force, required_angular_speed_rads
134
+
135
+ def calculate_energy_in(self, required_speed_kmh, gradients, wind_speeds, tick, **kwargs):
136
+ """
137
+
138
+ Create a function which takes in array of elevation, array of wind speed, required
139
+ speed, returns the consumed energy.
140
+
141
+ :param np.ndarray required_speed_kmh: (float[N]) required speed array in km/h
142
+ :param np.ndarray gradients: (float[N]) gradient at parts of the road
143
+ :param np.ndarray wind_speeds: (float[N]) speeds of wind in m/s, where > 0 means against the direction of the vehicle
144
+ :param float tick: length of 1 update cycle in seconds
145
+ :returns: (float[N]) energy expended by the motor at every tick
146
+ :rtype: np.ndarray
147
+
148
+ """
149
+ net_force, required_angular_speed_rads = self.calculate_net_force(required_speed_kmh, wind_speeds, gradients)
150
+
151
+ motor_output_energies = required_angular_speed_rads * net_force * self.tire_radius * tick
152
+ motor_output_energies = np.clip(motor_output_energies, a_min=0, a_max=None)
153
+
154
+ e_m = self.calculate_motor_efficiency(required_angular_speed_rads, motor_output_energies, tick)
155
+ e_mc = self.calculate_motor_controller_efficiency(required_angular_speed_rads, motor_output_energies, tick)
156
+
157
+ motor_controller_input_energies = motor_output_energies / (e_m * e_mc)
158
+
159
+ # Filter out and replace negative energy consumption as 0
160
+ motor_controller_input_energies = np.where(motor_controller_input_energies > 0,
161
+ motor_controller_input_energies, 0)
162
+
163
+ return motor_controller_input_energies
164
+
165
+ def __str__(self):
166
+ return (f"Tire radius: {self.tire_radius}m\n"
167
+ f"Rolling resistance coefficient: {self.road_friction}\n"
168
+ f"Vehicle mass: {self.vehicle_mass}kg\n"
169
+ f"Acceleration of gravity: {self.acceleration_g}m/s^2\n"
170
+ f"Motor controller efficiency: {self.e_mc}%\n"
171
+ f"Motor efficiency: {self.e_m}%\n")
172
+
173
+
174
+ def calculate_motor_efficiency(motor_output_power, revolutions_per_minute):
175
+ return 0.7382 - (6.281e-5 * motor_output_power) + (6.708e-4 * revolutions_per_minute) \
176
+ - (2.89e-8 * motor_output_power ** 2) + (2.416e-7 * motor_output_power * revolutions_per_minute) \
177
+ - (8.672e-7 * revolutions_per_minute ** 2) + (5.653e-12 * motor_output_power ** 3) \
178
+ - (1.74e-11 * motor_output_power ** 2 * revolutions_per_minute) \
179
+ - (7.322e-11 * motor_output_power * revolutions_per_minute ** 2) \
180
+ + (3.263e-10 * revolutions_per_minute ** 3)
181
+
182
+
183
+ def calculate_motor_controller_efficiency(motor_angular_speed, motor_torque_array):
184
+ return 0.7694 + (0.007818 * motor_angular_speed) + (0.007043 * motor_torque_array) \
185
+ - (1.658e-4 * motor_angular_speed ** 2) - (1.806e-5 * motor_torque_array * motor_angular_speed) \
186
+ - (1.909e-4 * motor_torque_array ** 2) + (1.602e-6 * motor_angular_speed ** 3) \
187
+ + (4.236e-7 * motor_angular_speed ** 2 * motor_torque_array) \
188
+ - (2.306e-7 * motor_angular_speed * motor_torque_array ** 2) \
189
+ + (2.122e-06 * motor_torque_array ** 3) - (5.701e-09 * motor_angular_speed ** 4) \
190
+ - (2.054e-9 * motor_angular_speed ** 3 * motor_torque_array) \
191
+ - (3.126e-10 * motor_angular_speed ** 2 * motor_torque_array ** 2) \
192
+ + (1.708e-09 * motor_angular_speed * motor_torque_array ** 3) \
193
+ - (8.094e-09 * motor_torque_array ** 4)
File without changes
@@ -0,0 +1 @@
1
+ mod motor;
@@ -0,0 +1,7 @@
1
+ from .base_regen import BaseRegen
2
+ from .basic_regen import BasicRegen
3
+
4
+ __all__ = [
5
+ "BasicRegen",
6
+ "BaseRegen"
7
+ ]
@@ -0,0 +1,6 @@
1
+ from abc import ABC
2
+
3
+
4
+ class BaseRegen(ABC):
5
+ def __init__(self):
6
+ super().__init__()
@@ -0,0 +1,52 @@
1
+ from physics.models.regen import BaseRegen
2
+ import numpy as np
3
+
4
+
5
+ class BasicRegen(BaseRegen):
6
+ GRAVITY = 9.81
7
+ EFFICIENCY = 0.5 # currently set to 50% but best case scenario is 60-70%
8
+
9
+ def __init__(self, vehicle_mass):
10
+ super().__init__()
11
+ self.min_decel_mag = 0
12
+ self.vehicle_mass = vehicle_mass
13
+ self.kmh_to_mps = 0.278
14
+
15
+ def get_regen_efficiency(self, speed_array):
16
+ """
17
+ Returns a numpy array of regen efficiency percentage based on the vehicle speed in m/s.
18
+
19
+ :param speed_array: a numpy array of speeds in m/s
20
+ :returns: numpy array of regen efficiency percentage
21
+ """
22
+ # Efficiency polynomial, more details can be found in regen_analysis folder located in data_analysis
23
+ efficiency_poly = [0.022288416685942, 0.026545396753597]
24
+
25
+ return np.polyval(efficiency_poly, speed_array)
26
+
27
+ def calculate_produced_energy(self, speed_kmh, gis_route_elevations, min_regen_speed, max_power):
28
+ """
29
+ Returns a numpy array containing the energy produced by regen
30
+ during each tick of the race based on the change in energy in that tick
31
+ :param speed_kmh: an array containing the speeds at each tick
32
+ :param gis_route_elevations: an array containing elevations on the route at each tick
33
+ """
34
+ # get the changes of energy from tick i to tick i + 1
35
+ speed_ms = speed_kmh / 3.6 # Convert to m/s from km/h
36
+ delta_kinetic_energy = np.diff((1 / 2) * self.vehicle_mass * pow(speed_ms, 2), append=[0])
37
+ delta_potential_energy = np.diff(self.vehicle_mass * self.GRAVITY * gis_route_elevations, append=[0])
38
+
39
+ # get the total change in energy at each tick
40
+ delta_energy = delta_kinetic_energy + delta_potential_energy
41
+
42
+ # create regen energy produced array
43
+ # if delta_energy is negative, we regen that energy back at the set efficiency rate; else 0 energy regen
44
+ efficiencies = self.get_regen_efficiency(speed_ms)
45
+ produced_energy = np.where(delta_energy < 0, abs(delta_energy) * efficiencies, 0)
46
+
47
+ # Regen does not occur below a certain speed
48
+ produced_energy = np.where(speed_ms >= min_regen_speed, produced_energy, 0)
49
+
50
+ # Regen power is capped by current limitations
51
+
52
+ return np.clip(produced_energy, a_min=0, a_max=max_power)
File without changes
@@ -0,0 +1 @@
1
+ mod regen;
physics/models.rs ADDED
@@ -0,0 +1,5 @@
1
+ mod arrays;
2
+ pub mod battery;
3
+ mod lvs;
4
+ mod motor;
5
+ mod regen;
@@ -0,0 +1,111 @@
1
+ import numpy as np
2
+
3
+
4
+ def constrain_speeds(speed_limits: np.ndarray, speeds: np.ndarray, tick: int) -> np.ndarray:
5
+ """
6
+ Constrains the vehicle speeds based on the speed limits and computes new speeds.
7
+
8
+ :param speed_limits: Array of speed limits (km/h) for each point.
9
+ :param speeds: Array of vehicle speeds (km/h).
10
+ :param tick: The time step (in some unit, e.g., seconds or ticks).
11
+
12
+ :return: A NumPy array of constrained vehicle speeds (km/h).
13
+ """
14
+ ...
15
+
16
+
17
+ def calculate_array_ghi_times(python_local_times: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
18
+ """
19
+ Calculates the array of GHI times based on local times.
20
+
21
+ :param python_local_times: Array of local times (UNIX timestamps or other format).
22
+
23
+ :return: A tuple of two NumPy arrays:
24
+ - Day of year (f64)
25
+ - Local time (f64)
26
+ """
27
+ ...
28
+
29
+
30
+ def closest_gis_indices_loop(python_cumulative_distances: np.ndarray,
31
+ python_average_distances: np.ndarray) -> np.ndarray:
32
+ """
33
+ Finds the closest GIS indices based on cumulative and average distances.
34
+
35
+ :param python_cumulative_distances: Array of cumulative distances.
36
+ :param python_average_distances: Array of average distances.
37
+
38
+ :return: A NumPy array of indices (i64) corresponding to the closest GIS indices.
39
+ """
40
+ ...
41
+
42
+
43
+ def closest_weather_indices_loop(
44
+ python_cumulative_distances: np.ndarray,
45
+ python_average_distances: np.ndarray
46
+ ) -> np.ndarray:
47
+ """
48
+ Finds the closest weather indices based on cumulative and average distances.
49
+
50
+ :param python_cumulative_distances: Array of cumulative distances.
51
+ :param python_average_distances: Array of average distances.
52
+
53
+ :return: A NumPy array of indices (i64) corresponding to the closest weather indices.
54
+ """
55
+ ...
56
+
57
+
58
+ def weather_in_time(
59
+ python_unix_timestamps: np.ndarray,
60
+ python_indices: np.ndarray,
61
+ python_weather_forecast: np.ndarray,
62
+ index: int
63
+ ) -> np.ndarray:
64
+ """
65
+ Retrieves the weather forecast at specific times for given indices.
66
+
67
+ :param python_unix_timestamps: Array of UNIX timestamps.
68
+ :param python_indices: Array of indices to look up.
69
+ :param python_weather_forecast: Array of weather forecasts.
70
+ :param index: A specific index to look up in the weather forecast.
71
+
72
+ :return: A NumPy array of weather values (f64) at the specified times and indices.
73
+ """
74
+ ...
75
+
76
+
77
+ def update_battery_state(
78
+ python_energy_or_current_array: np.ndarray,
79
+ time_step: float,
80
+ initial_state_of_charge: float,
81
+ initial_polarization_potential: float,
82
+ python_internal_resistance_lookup: np.ndarray,
83
+ python_open_circuit_voltage_lookup: np.ndarray,
84
+ python_polarization_resistance_lookup: np.ndarray,
85
+ python_polarization_capacitance_lookup: np.ndarray,
86
+ nominal_charge_capacity: float,
87
+ is_power: bool,
88
+ quantization_step: float,
89
+ min_soc: float
90
+ ) -> tuple[np.ndarray, np.ndarray]:
91
+ """
92
+ Updates the battery state (SOC and terminal voltage) based on energy/current input.
93
+
94
+ :param python_energy_or_current_array: Array of energy or current input values (f64).
95
+ :param time_step: Time step (f64).
96
+ :param initial_state_of_charge: Initial state of charge (f64).
97
+ :param initial_polarization_potential: Initial polarization potential (f64).
98
+ :param python_internal_resistance_lookup: Array of internal resistance values (f64).
99
+ :param python_open_circuit_voltage_lookup: Array of open-circuit voltage values (f64).
100
+ :param python_polarization_resistance_lookup: Array of polarization resistance values (f64).
101
+ :param python_polarization_capacitance_lookup: Array of polarization capacitance values (f64).
102
+ :param nominal_charge_capacity: Nominal charge capacity (f64).
103
+ :param is_power: Boolean flag to indicate if the input is power (`True`) or current (`False`).
104
+ :param quantization_step: The step size used to quantize the SOC (f64).
105
+ :param min_soc: The minimum SOC used when computing the lookup tables
106
+
107
+ :return: A tuple containing:
108
+ - An array of updated SOC values (f64).
109
+ - An array of updated terminal voltage values (f64).
110
+ """
111
+ ...
Binary file
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 UBC Solar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,142 @@
1
+ Metadata-Version: 2.1
2
+ Name: ubc-solar-physics
3
+ Version: 1.7.3
4
+ Summary: UBC Solar's Simulation Environment
5
+ Author: Fisher Xue, Mihir Nimgade, Chris Chang, David Widjaja, Justin Hua, Ilya Veksler, Renu Rajamagesh, Ritchie Xia, Erik Langille, Chris Aung, Nicolas Ric, Ishaan Trivedi, Jason Liang, Felix Toft, Mack Wilson, Jonah Lee, Tamzeed Quazi, Joshua Riefman
6
+ Author-email: UBC Solar <strategy@ubcsolar.com>
7
+ Maintainer: Renu Rajamagmesh, Felix Toft, Mack Wilson, Jonah Lee, Tamzeed Quazi
8
+ Maintainer-email: UBC Solar <strategy@ubcsolar.com>, Joshua Riefman <joshuariefman@gmail.com>
9
+ License: MIT License
10
+
11
+ Copyright (c) 2024 UBC Solar
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+
31
+ Project-URL: Homepage, https://ubcsolar.com
32
+ Project-URL: Repository, https://github.com/UBC-Solar/physics
33
+ Project-URL: Documentation, https://ubc-solar-physics.readthedocs.io/en/latest/
34
+ Keywords: car,simulation,solar
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Rust
37
+ Classifier: Natural Language :: English
38
+ Classifier: Topic :: Scientific/Engineering :: Physics
39
+ Requires-Python: >=3.9
40
+ Description-Content-Type: text/markdown
41
+ License-File: LICENSE
42
+ Requires-Dist: backports.tarfile ==1.2.0
43
+ Requires-Dist: certifi ==2024.7.4
44
+ Requires-Dist: charset-normalizer ==3.3.2
45
+ Requires-Dist: dill >=0.3.8
46
+ Requires-Dist: haversine ==2.8.1
47
+ Requires-Dist: idna ==3.7
48
+ Requires-Dist: importlib-metadata ==8.2.0
49
+ Requires-Dist: jaraco.classes ==3.4.0
50
+ Requires-Dist: jaraco.context ==5.3.0
51
+ Requires-Dist: jaraco.functools ==4.0.2
52
+ Requires-Dist: keyring ==25.3.0
53
+ Requires-Dist: llvmlite
54
+ Requires-Dist: markdown-it-py ==3.0.0
55
+ Requires-Dist: mdurl ==0.1.2
56
+ Requires-Dist: more-itertools ==10.4.0
57
+ Requires-Dist: nh3 ==0.2.18
58
+ Requires-Dist: numba
59
+ Requires-Dist: numpy >=2
60
+ Requires-Dist: pkginfo ==1.10.0
61
+ Requires-Dist: Pygments ==2.18.0
62
+ Requires-Dist: readme-renderer ==44.0
63
+ Requires-Dist: requests ==2.32.3
64
+ Requires-Dist: requests-toolbelt ==1.0.0
65
+ Requires-Dist: rfc3986 ==2.0.0
66
+ Requires-Dist: rich ==13.7.1
67
+ Requires-Dist: tqdm ==4.66.5
68
+ Requires-Dist: urllib3 ==2.2.2
69
+ Requires-Dist: zipp ==3.20.0
70
+ Requires-Dist: filterpy ==1.4.5
71
+ Requires-Dist: toml ==0.10.2
72
+ Requires-Dist: pandas
73
+ Requires-Dist: pydantic ==2.9.2
74
+ Requires-Dist: scipy
75
+ Requires-Dist: tomli
76
+ Requires-Dist: scipy-stubs
77
+
78
+ # UBC Solar Physics
79
+
80
+ <!-- marker-index-start -->
81
+
82
+ [![Documentation Status](https://readthedocs.org/projects/ubc-solar-physics/badge/?version=latest)](https://ubc-solar-physics.readthedocs.io/en/latest/?badge=latest)
83
+
84
+ UBC Solar's physics and environment models for simulating our groundbreaking solar cars.
85
+
86
+ The API is currently unstable, and backwards compatibility may not be maintained.
87
+
88
+ ## Requirements
89
+
90
+ Versions indicated are recommended
91
+
92
+ * Git [^1]
93
+ * Python >=3.9 [^2]
94
+ * Rustc >=1.79.0 [^3]
95
+ * Cargo >=1.79.0 [^4]
96
+
97
+ ## Installation
98
+
99
+ First, clone this repository.
100
+
101
+ ```bash
102
+ git clone https://github.com/UBC-Solar/physics.git
103
+ ```
104
+ Then, create and activate a virtual environment.
105
+ Next, install dependencies in editable mode.
106
+
107
+ ```bash
108
+ pip3 install -e .
109
+ ```
110
+
111
+ ## Getting Started
112
+
113
+ Example of calculating solar arrays produced energy
114
+
115
+ ```python
116
+ from physics.models.arrays import BasicArray
117
+ import numpy as np
118
+
119
+ efficiency = 0.25 # 25.0% efficient
120
+ panel_size = 4.0 # 4.0m^2 of panels
121
+ tick = 1.0 # 1.0s interval
122
+
123
+ arrays = BasicArray(panel_efficiency=efficiency, panel_size=panel_size)
124
+
125
+ irradiance = np.full([5], 400.0) # 10 seconds of 400.0W/m^2 irradiance
126
+
127
+ solar_power_produced = arrays.calculate_produced_energy(solar_irradiance=irradiance, tick=tick)
128
+
129
+ assert np.array_equal(solar_power_produced, np.array([400.0, 400.0, 400.0, 400.0, 400.0]))
130
+ ```
131
+
132
+ ## Appendix
133
+
134
+ [^1]: use `git --version` to verify version
135
+
136
+ [^2]: use `python3 --version` to verify version
137
+
138
+ [^3]: use `rustc --version` to verify version
139
+
140
+ [^4]: use `cargo --version` to verify version
141
+
142
+ <!-- marker-index-end -->
@@ -0,0 +1,57 @@
1
+ physics_rs.cpython-39-darwin.so,sha256=o8xaflAtvNFFbugV9I6z27vUGHXCXg4Q_t3Ewj_IZZo,678380
2
+ physics_rs/__init__.pyi,sha256=bMMIbLFgpSYq37i9xHpvdoVlMuI7IRZ9bdbLCcIBeO8,4235
3
+ physics/_version.py,sha256=Lv0gR-NbC-8DxwfmwXEmOzSq6Hgx6MH4xF1fYh_opXo,411
4
+ physics/lib.rs,sha256=BGgj8jwbWQ7mkBDfKyTqH5jZGKAAb9U0sSByUaI-Los,7169
5
+ physics/models.rs,sha256=N5342VhLaLSlPLHZ7s1VDIEPY76-rQN03lY_wd2HS1A,59
6
+ physics/__init__.py,sha256=7939mrehCy0ogupHq26hUk1MkAjh2xmbD30GscdC_D8,169
7
+ physics/environment.rs,sha256=VWX1haUCO-WenD0dawS5FxY9dquiUT6Uud3p3dAnJZA,34
8
+ physics/models/battery.rs,sha256=fTL9O20fQarT_CFsmMSqVEZNe_sTejWMaAR8Fc-z_ak,16
9
+ physics/models/lvs.rs,sha256=uyJ1ZZ1Phq8cWCzr2aevCWzt8MlhCw9DO5ObUvEs8ds,8
10
+ physics/models/constants.py,sha256=mw0IkjhSJe51inbbzvVpHnpGLY_AoWxIxjfjcUF4cd8,816
11
+ physics/models/motor.rs,sha256=Iya1C_YF09KMy-9N-Mt-rBf1EIAs2Bf3Q4eDvyFuAoc,10
12
+ physics/models/arrays.rs,sha256=rtthXq7PDjL30lIt8y9L2xFAPJE5o_ltmCbOGzzOxrc,11
13
+ physics/models/__init__.py,sha256=msz4YtXe7fsGr-FsV-yJK0frN5XrmsXPSAkpS8lxHW8,255
14
+ physics/models/regen.rs,sha256=WXwtzB72akG6L17wg-9Pz9kUe-57lqh4-PcSv1cKrGU,10
15
+ physics/models/lvs/basic_lvs.py,sha256=UH6VmVWrSo-tKvcbSOm3Ptp0edz1xDQiQsM4HlOJ__0,603
16
+ physics/models/lvs/lvs.rs,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ physics/models/lvs/__init__.py,sha256=GkO6SJxbbSnXYLdMDvsvTRhXotV3zaRNmYBgziQLGB8,107
18
+ physics/models/lvs/base_lvs.py,sha256=PVwPgCaJ_TcV2mQf3X2pngi0aG-jTLTeloL-LQV3jMU,110
19
+ physics/models/motor/advanced_motor.py,sha256=EL86tCDSQCTT55EdXnmtPaIL9YS2o5p2u3QiLuoZuCA,8758
20
+ physics/models/motor/motor.rs,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ physics/models/motor/__init__.py,sha256=zkV7LiAozFNu9CRWWXeCbCDepjsaUIYT8Q2dkXJgLsM,183
22
+ physics/models/motor/basic_motor.py,sha256=-_rKIFCRRLniC1yHr_8fRsmj6xvHuAzPqA168vTDkds,8626
23
+ physics/models/motor/base_motor.py,sha256=34wy8x945HvJijn9267fdAR_JNHxH_7bYxYbVl71WBA,97
24
+ physics/models/arrays/basic_array.py,sha256=cGBwyrYpR313ECJ-SwnrK3JzYo24NRE70j8sj-sxFQI,1332
25
+ physics/models/arrays/base_array.py,sha256=ZUjehd7vwNOBdFLUk9WJUeGOi9DPopYplH1gqAMnKgA,95
26
+ physics/models/arrays/arrays.rs,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ physics/models/arrays/__init__.py,sha256=yavs1K3JA6x3Aa-U1JCZJlcWggCOFrVxrrMCGsiceAw,119
28
+ physics/models/battery/battery_config.toml,sha256=Fn1pb3NJJ_nclxm9nfGEQKmJYA2d5a9jCAUbwUGu6Uw,1092
29
+ physics/models/battery/battery.rs,sha256=10NAAGg99gQ70Kjd4kVuVHBxp3J6AgXfxEYKZUzu5DQ,5275
30
+ physics/models/battery/basic_battery.py,sha256=u0aO_iWKicVRECbDzLIs8goaWD5tLMnYGNe948lKC7U,5754
31
+ physics/models/battery/__init__.py,sha256=bIESRM8eEpaKSYMoliXD7rs3TUkAawTN9i3-YB2WCZg,630
32
+ physics/models/battery/battery_config.py,sha256=V4CfzUTcOFcizpDU9-Ujn2zXbUnAqrhyARN9QXGH6fk,4052
33
+ physics/models/battery/kalman_filter.py,sha256=kcX3SU1mNiY4-2YCUWAvqyTX6Cww7Pq7zaxaqh8ltgM,8725
34
+ physics/models/battery/base_battery.py,sha256=yK-bkA2OolE6nIDn5rf5nzi8gwm-AqQRmgsQioi_UOA,1203
35
+ physics/models/battery/battery_model.py,sha256=kODVlBZAIpPD_EB0UPlOeQv5HP-tMu6S-C6mEOJMHv4,10264
36
+ physics/models/regen/basic_regen.py,sha256=kcp6Wkw2o72xO_0-UCNABWSC_QIkexcS72iblNVQFBA,2350
37
+ physics/models/regen/base_regen.py,sha256=nWtmsm47wp9mx261OmSILwja32yYhzCLSNXWnzt82TY,95
38
+ physics/models/regen/__init__.py,sha256=51t_BHuQqIVPPy_0b14MO6QGZayOO326JR7wK1egy-g,119
39
+ physics/models/regen/regen.rs,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ physics/environment/__init__.py,sha256=eFWp8YFvL3CSXE5cZ24AcIjmW7vMUyh97sr9HZabw_U,210
41
+ physics/environment/gis.rs,sha256=9R7G0cjf5PxQAz-CSryA6-KGfrh1eSwRhJ6qF8KfjDE,12
42
+ physics/environment/environment.rs,sha256=yvzrjKHZ5vRvVip6lM34i8E0Ell_5fC3zyJDsb0h5nc,33
43
+ physics/environment/meteorology.rs,sha256=naWb7qYrtMkCE_tLAkM474fmxaufhCkyhy3TTUQ4Yw4,20
44
+ physics/environment/meteorology/__init__.py,sha256=569as2j7kpv8Nh75M9xk9e7rTqsDPGo3Ii3nskD6F34,154
45
+ physics/environment/meteorology/base_meteorology.py,sha256=d5TDNLUIBmTkLtJhv9qUq9KcfNKxzoM7xIOsfyNbwfI,2418
46
+ physics/environment/meteorology/irradiant_meteorology.py,sha256=1kqX4nEOUw-CYrLTusG6BdoZbZt_GEpfKMyey8YzLr0,5615
47
+ physics/environment/meteorology/clouded_meteorology.py,sha256=aEqlozaMOyhhxGK7CCD6BVHAn_HZDpSAUwGUngikkp4,27665
48
+ physics/environment/meteorology/meteorology.rs,sha256=Q3toiZv8M1updhoAnFDZ87YPy1afC9chUkF2IP9uA-I,5004
49
+ physics/environment/gis/base_gis.py,sha256=eVr4G7wAGlx6VsrCt2OuI8WzUMM50h2sHHvw8BOBur8,1046
50
+ physics/environment/gis/__init__.py,sha256=Kp85UC1WvcAMBxbgvwaMTEk8ELYzwUJLCtP0e1hnMvM,90
51
+ physics/environment/gis/gis.rs,sha256=_vXYMr7vNCC8Ip3CpQdyl6FA_3tCvOZeJd0-J5t4Eps,4865
52
+ physics/environment/gis/gis.py,sha256=EAFDudUmLWCBtM5A_LO3-MV-98tj-Q3s7S2WaoJjUGg,13209
53
+ ubc_solar_physics-1.7.3.dist-info/RECORD,,
54
+ ubc_solar_physics-1.7.3.dist-info/LICENSE,sha256=DAej6EJNqQWTair3XPAQiqoJbly4BAT1JMOsZxoZvH0,1066
55
+ ubc_solar_physics-1.7.3.dist-info/WHEEL,sha256=m4IOf_1HRvKHILOz7tWshkOf86rqw7oHbHPVLDAMJNk,109
56
+ ubc_solar_physics-1.7.3.dist-info/top_level.txt,sha256=jBZ5oyp1QQOrKodHG2UH9PMPEiZtza_q3y6fp3lEmQs,19
57
+ ubc_solar_physics-1.7.3.dist-info/METADATA,sha256=GNE035peFVy6NH3Fy6Posh3nim_JTJhlgcV1BDtljeU,5002
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (74.1.3)
3
+ Root-Is-Purelib: false
4
+ Tag: cp39-cp39-macosx_10_12_x86_64
5
+
@@ -0,0 +1,2 @@
1
+ physics
2
+ physics_rs