ubc-solar-physics 1.7.10__cp312-cp312-macosx_10_12_x86_64.whl → 1.8.0__cp312-cp312-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.
- physics/_version.py +2 -2
- physics/environment/gis/base_gis.py +7 -1
- physics/environment/gis/gis.py +51 -16
- physics/environment/gis/gis.rs +38 -0
- physics/lib.rs +24 -1
- physics_rs.cpython-312-darwin.so +0 -0
- {ubc_solar_physics-1.7.10.dist-info → ubc_solar_physics-1.8.0.dist-info}/METADATA +1 -1
- {ubc_solar_physics-1.7.10.dist-info → ubc_solar_physics-1.8.0.dist-info}/RECORD +11 -11
- {ubc_solar_physics-1.7.10.dist-info → ubc_solar_physics-1.8.0.dist-info}/LICENSE +0 -0
- {ubc_solar_physics-1.7.10.dist-info → ubc_solar_physics-1.8.0.dist-info}/WHEEL +0 -0
- {ubc_solar_physics-1.7.10.dist-info → ubc_solar_physics-1.8.0.dist-info}/top_level.txt +0 -0
physics/_version.py
CHANGED
@@ -24,6 +24,11 @@ class BaseGIS(ABC):
|
|
24
24
|
def get_path(self) -> np.ndarray:
|
25
25
|
raise NotImplementedError
|
26
26
|
|
27
|
+
@staticmethod
|
28
|
+
@abstractmethod
|
29
|
+
def calculate_speeds_and_position(speeds_kmh: NDArray, track_speeds, path_distances, dt):
|
30
|
+
raise NotImplementedError
|
31
|
+
|
27
32
|
@abstractmethod
|
28
33
|
def calculate_current_heading_array(self) -> np.ndarray:
|
29
34
|
raise NotImplementedError
|
@@ -33,6 +38,7 @@ class BaseGIS(ABC):
|
|
33
38
|
average_lap_speeds: ArrayLike,
|
34
39
|
simulation_dt: int,
|
35
40
|
driving_allowed: ArrayLike,
|
36
|
-
idle_time: int
|
41
|
+
idle_time: int,
|
42
|
+
laps_per_speed: int
|
37
43
|
) -> NDArray[float]:
|
38
44
|
raise NotImplementedError
|
physics/environment/gis/gis.py
CHANGED
@@ -34,21 +34,9 @@ class GIS(BaseGIS):
|
|
34
34
|
self.path_time_zones = route_data['time_zones']
|
35
35
|
self.num_unique_coords = route_data['num_unique_coords']
|
36
36
|
|
37
|
-
|
38
|
-
if not np.array_equal(current_coord, origin_coord):
|
39
|
-
logging.warning("Current position is not origin position. Modifying path data.\n")
|
40
|
-
|
41
|
-
# We need to find the closest coordinate along the path to the vehicle position
|
42
|
-
current_coord_index = GIS._find_closest_coordinate_index(current_coord, self.path)
|
43
|
-
|
44
|
-
# All coords before the current coordinate should be discarded
|
45
|
-
self.path = self.path[current_coord_index:]
|
46
|
-
self.path_elevations = self.path_elevations[current_coord_index:]
|
47
|
-
self.path_time_zones = self.path_time_zones[current_coord_index:]
|
48
|
-
|
49
|
-
self.path_distances = calculate_path_distances(self.path)
|
37
|
+
self.path_distances = calculate_path_distances(self.path)[:self.num_unique_coords]
|
50
38
|
self.path_length = np.cumsum(calculate_path_distances(self.path[:self.num_unique_coords]))[-1]
|
51
|
-
self.path_gradients = calculate_path_gradients(self.path_elevations, self.path_distances)
|
39
|
+
self.path_gradients = calculate_path_gradients(self.path_elevations[:self.num_unique_coords], self.path_distances)
|
52
40
|
|
53
41
|
@staticmethod
|
54
42
|
def process_KML_file(route_file):
|
@@ -83,12 +71,58 @@ class GIS(BaseGIS):
|
|
83
71
|
"""
|
84
72
|
return physics_rs.closest_gis_indices_loop(distances, self.path_distances)
|
85
73
|
|
74
|
+
def calculate_speeds_and_position(self, speeds_kmh: NDArray, track_speeds: NDArray, dt: int):
|
75
|
+
try:
|
76
|
+
return physics_rs.calculate_speeds_and_position(speeds_kmh, self.path_distances, track_speeds, dt)
|
77
|
+
|
78
|
+
except Exception:
|
79
|
+
return self._py_calculate_speeds_and_position(speeds_kmh, track_speeds, dt)
|
80
|
+
|
81
|
+
def _py_calculate_speeds_and_position(self, speeds_kmh: NDArray, track_speeds: NDArray, dt: int):
|
82
|
+
"""
|
83
|
+
Given the original, lap-averaged `speeds_kmh` and an array of speed deviations in km/h for each track index,
|
84
|
+
compute the position and actual speed as simulation-time arrays.
|
85
|
+
|
86
|
+
:param speeds_kmh: Lap-averaged speeds in km/h.
|
87
|
+
:param track_speeds: A speed deviation in km/h for each track index. Expects the mean to be at 0.
|
88
|
+
:param dt:
|
89
|
+
:return:
|
90
|
+
"""
|
91
|
+
result = []
|
92
|
+
actual_speeds_kmh = []
|
93
|
+
|
94
|
+
with tqdm(total=len(speeds_kmh), file=sys.stdout, desc="Calculating closest GIS indices") as pbar:
|
95
|
+
distance_travelled = 0
|
96
|
+
track_index = 0
|
97
|
+
|
98
|
+
for lap_speed in speeds_kmh:
|
99
|
+
if lap_speed > 0:
|
100
|
+
actual_speed = lap_speed + track_speeds[track_index]
|
101
|
+
else:
|
102
|
+
actual_speed = 0
|
103
|
+
|
104
|
+
actual_speeds_kmh.append(actual_speed)
|
105
|
+
distance_travelled += actual_speed * dt
|
106
|
+
|
107
|
+
while distance_travelled > self.path_distances[track_index]:
|
108
|
+
distance_travelled -= self.path_distances[track_index]
|
109
|
+
track_index += 1
|
110
|
+
|
111
|
+
if track_index >= len(self.path_distances):
|
112
|
+
track_index = 0
|
113
|
+
|
114
|
+
result.append(track_index)
|
115
|
+
pbar.update(1)
|
116
|
+
|
117
|
+
return np.array(result), np.array(actual_speeds_kmh)
|
118
|
+
|
86
119
|
def calculate_driving_speeds(
|
87
120
|
self,
|
88
121
|
average_lap_speeds: ArrayLike,
|
89
122
|
simulation_dt: int,
|
90
123
|
driving_allowed: ArrayLike,
|
91
|
-
idle_time: int
|
124
|
+
idle_time: int,
|
125
|
+
laps_per_speed: int
|
92
126
|
) -> NDArray[float]:
|
93
127
|
"""
|
94
128
|
Generate valid driving speeds as a simulation-time array given a set of average speeds for each
|
@@ -105,6 +139,7 @@ class GIS(BaseGIS):
|
|
105
139
|
are allowed to drive, and `False` is when we are not. Requires that (at least) the first element is
|
106
140
|
`False` due to the race beginning in the morning before we are allowed to drive.
|
107
141
|
:param idle_time: The length of time to pause driving upon processing a "0m/s" average speed.
|
142
|
+
:param laps_per_speed: The amount of laps that we expect to use with each speed value.
|
108
143
|
:return: A simulation-time array of driving speeds in m/s, or an error if there weren't enough
|
109
144
|
laps provided to fill the entire simulation time.
|
110
145
|
"""
|
@@ -112,7 +147,7 @@ class GIS(BaseGIS):
|
|
112
147
|
np.array(average_lap_speeds).astype(np.float64),
|
113
148
|
simulation_dt,
|
114
149
|
np.array(driving_allowed).astype(bool),
|
115
|
-
self.path_length,
|
150
|
+
self.path_length * laps_per_speed,
|
116
151
|
idle_time
|
117
152
|
)
|
118
153
|
|
physics/environment/gis/gis.rs
CHANGED
@@ -26,6 +26,44 @@ pub fn rust_closest_gis_indices_loop(
|
|
26
26
|
result
|
27
27
|
}
|
28
28
|
|
29
|
+
pub fn calculate_speeds_and_position(
|
30
|
+
speeds_kmh: ArrayView1<'_, f64>,
|
31
|
+
path_distances: ArrayView1<'_, f64>,
|
32
|
+
track_speeds: ArrayView1<'_, f64>,
|
33
|
+
simulation_dt: u32,
|
34
|
+
) -> (Vec<usize>, Vec<f64>) {
|
35
|
+
let mut track_index: usize = 0;
|
36
|
+
let mut distance_travelled: f64 = 0.0;
|
37
|
+
let n = path_distances.len();
|
38
|
+
|
39
|
+
let mut result: Vec<usize> = Vec::with_capacity(speeds_kmh.len());
|
40
|
+
let mut actual_speeds_kmh: Vec<f64> = Vec::with_capacity(speeds_kmh.len());
|
41
|
+
|
42
|
+
for &speed in speeds_kmh {
|
43
|
+
let actual_speed = if speed > 0.0 {
|
44
|
+
speed + track_speeds[track_index]
|
45
|
+
} else {
|
46
|
+
0.0
|
47
|
+
};
|
48
|
+
|
49
|
+
actual_speeds_kmh.push(actual_speed);
|
50
|
+
distance_travelled += actual_speed * simulation_dt as f64;
|
51
|
+
|
52
|
+
while distance_travelled > path_distances[track_index] {
|
53
|
+
distance_travelled -= path_distances[track_index];
|
54
|
+
track_index += 1;
|
55
|
+
|
56
|
+
if track_index >= n {
|
57
|
+
track_index = 0;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
result.push(track_index);
|
62
|
+
}
|
63
|
+
|
64
|
+
(result, actual_speeds_kmh)
|
65
|
+
}
|
66
|
+
|
29
67
|
///
|
30
68
|
/// Generate valid driving speeds as a simulation-time array given a set of average speeds for each
|
31
69
|
/// simulated lap.
|
physics/lib.rs
CHANGED
@@ -5,7 +5,7 @@ use pyo3::types::PyModule;
|
|
5
5
|
|
6
6
|
pub mod environment;
|
7
7
|
pub mod models;
|
8
|
-
use crate::environment::gis::gis::{rust_closest_gis_indices_loop, get_driving_speeds};
|
8
|
+
use crate::environment::gis::gis::{rust_closest_gis_indices_loop, get_driving_speeds, calculate_speeds_and_position};
|
9
9
|
use crate::environment::meteorology::meteorology::{rust_calculate_array_ghi_times, rust_closest_weather_indices_loop, rust_weather_in_time};
|
10
10
|
use crate::models::battery::battery::update_battery_state;
|
11
11
|
|
@@ -135,6 +135,29 @@ fn rust_simulation(_py: Python, m: &PyModule) -> PyResult<()> {
|
|
135
135
|
(py_soc_array, py_voltage_array)
|
136
136
|
}
|
137
137
|
|
138
|
+
#[pyfn(m)]
|
139
|
+
#[pyo3(name = "calculate_speeds_and_position")]
|
140
|
+
fn calculate_speeds_and_position_py<'py>(
|
141
|
+
py: Python<'py>,
|
142
|
+
speeds_kmh_py: PyReadwriteArray1<'py, f64>,
|
143
|
+
path_distances_py: PyReadwriteArray1<'py, f64>,
|
144
|
+
track_speeds_py: PyReadwriteArray1<'py, f64>,
|
145
|
+
simulation_dt: u32,
|
146
|
+
) -> (&'py PyArray1<usize>, &'py PyArray1<f64>) {
|
147
|
+
let speeds_kmh = speeds_kmh_py.as_array();
|
148
|
+
let path_distances = path_distances_py.as_array();
|
149
|
+
let track_speeds = track_speeds_py.as_array();
|
150
|
+
let (gis_indices, actual_speeds_kmh): (Vec<usize>, Vec<f64>) = calculate_speeds_and_position(
|
151
|
+
speeds_kmh,
|
152
|
+
path_distances,
|
153
|
+
track_speeds,
|
154
|
+
simulation_dt,
|
155
|
+
);
|
156
|
+
let gis_indices_py = PyArray::from_vec(py, gis_indices);
|
157
|
+
let actual_speeds_kmh_py = PyArray::from_vec(py, actual_speeds_kmh);
|
158
|
+
(gis_indices_py, actual_speeds_kmh_py)
|
159
|
+
}
|
160
|
+
|
138
161
|
#[pyfn(m)]
|
139
162
|
#[pyo3(name = "get_driving_speeds")]
|
140
163
|
fn py_get_driving_speeds<'py>(
|
physics_rs.cpython-312-darwin.so
CHANGED
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ubc-solar-physics
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.8.0
|
4
4
|
Summary: UBC Solar's Simulation Environment
|
5
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
6
|
Author-email: UBC Solar <strategy@ubcsolar.com>
|
@@ -1,12 +1,12 @@
|
|
1
|
-
physics_rs.cpython-312-darwin.so,sha256=
|
1
|
+
physics_rs.cpython-312-darwin.so,sha256=liyL3Byo6EHgeN4l00mTMKdHdV0Yfulor8ebw5TqjNk,675500
|
2
2
|
physics_rs/__init__.pyi,sha256=bMMIbLFgpSYq37i9xHpvdoVlMuI7IRZ9bdbLCcIBeO8,4235
|
3
|
-
ubc_solar_physics-1.
|
4
|
-
ubc_solar_physics-1.
|
5
|
-
ubc_solar_physics-1.
|
6
|
-
ubc_solar_physics-1.
|
7
|
-
ubc_solar_physics-1.
|
8
|
-
physics/_version.py,sha256=
|
9
|
-
physics/lib.rs,sha256=
|
3
|
+
ubc_solar_physics-1.8.0.dist-info/RECORD,,
|
4
|
+
ubc_solar_physics-1.8.0.dist-info/LICENSE,sha256=DAej6EJNqQWTair3XPAQiqoJbly4BAT1JMOsZxoZvH0,1066
|
5
|
+
ubc_solar_physics-1.8.0.dist-info/WHEEL,sha256=21fdHO2SyBOt18Wu0xihlb6XwWRW98FLg_zmZNNaTTs,111
|
6
|
+
ubc_solar_physics-1.8.0.dist-info/top_level.txt,sha256=jBZ5oyp1QQOrKodHG2UH9PMPEiZtza_q3y6fp3lEmQs,19
|
7
|
+
ubc_solar_physics-1.8.0.dist-info/METADATA,sha256=sXqx7OgmIQYv-QchnNM3c-LyjvhRVshUFj3aoa4U_UE,5002
|
8
|
+
physics/_version.py,sha256=PikY8ZcokXQcck_OODdQtYmXxEq-zKRR9b1ZMOFZlds,411
|
9
|
+
physics/lib.rs,sha256=uMeIRNVeeIpaxvvNM7qvCoSUzTzOdwOBEff_fP9XH18,8161
|
10
10
|
physics/models.rs,sha256=N5342VhLaLSlPLHZ7s1VDIEPY76-rQN03lY_wd2HS1A,59
|
11
11
|
physics/__init__.py,sha256=7939mrehCy0ogupHq26hUk1MkAjh2xmbD30GscdC_D8,169
|
12
12
|
physics/environment.rs,sha256=VWX1haUCO-WenD0dawS5FxY9dquiUT6Uud3p3dAnJZA,34
|
@@ -51,7 +51,7 @@ physics/environment/meteorology/base_meteorology.py,sha256=d5TDNLUIBmTkLtJhv9qUq
|
|
51
51
|
physics/environment/meteorology/irradiant_meteorology.py,sha256=1kqX4nEOUw-CYrLTusG6BdoZbZt_GEpfKMyey8YzLr0,5615
|
52
52
|
physics/environment/meteorology/clouded_meteorology.py,sha256=aEqlozaMOyhhxGK7CCD6BVHAn_HZDpSAUwGUngikkp4,27665
|
53
53
|
physics/environment/meteorology/meteorology.rs,sha256=Q3toiZv8M1updhoAnFDZ87YPy1afC9chUkF2IP9uA-I,5004
|
54
|
-
physics/environment/gis/base_gis.py,sha256=
|
54
|
+
physics/environment/gis/base_gis.py,sha256=iycttQ_bL2WXXQyXn9LokH8dv0ekQvCOJ0ONch__mYM,1246
|
55
55
|
physics/environment/gis/__init__.py,sha256=Kp85UC1WvcAMBxbgvwaMTEk8ELYzwUJLCtP0e1hnMvM,90
|
56
|
-
physics/environment/gis/gis.rs,sha256=
|
57
|
-
physics/environment/gis/gis.py,sha256=
|
56
|
+
physics/environment/gis/gis.rs,sha256=YEJ_0PkwYZfCg1TxEKLAKrpy4UdZTJLItQZVQMIULTc,5947
|
57
|
+
physics/environment/gis/gis.py,sha256=KTtztphHaiU3oHgeUXVUtSa2XLUqg4iaYaSAFFJVBTQ,14531
|
File without changes
|
File without changes
|
File without changes
|