|
3 | 3 | from typing import Any |
4 | 4 |
|
5 | 5 | import numpy as np |
| 6 | +from Basilisk.utilities.RigidBodyKinematics import MRP2C |
6 | 7 |
|
7 | 8 | from bsk_rl.obs import Observation |
8 | | -from bsk_rl.utils.orbital import rv2omega |
| 9 | +from bsk_rl.utils.orbital import rv2HN, rv2omega |
9 | 10 |
|
10 | 11 |
|
11 | 12 | def r_DC_N(deputy, chief): |
@@ -86,6 +87,53 @@ def sigma_HdHc(deputy, chief): |
86 | 87 | # frame to express in) |
87 | 88 |
|
88 | 89 |
|
| 90 | +def rso_imaged_regions( |
| 91 | + servicer, |
| 92 | + chief, |
| 93 | + region_centers=np.array( |
| 94 | + [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]] |
| 95 | + ), |
| 96 | + frame="chief_hill", |
| 97 | +): |
| 98 | + """For use with the RSO tasking scenario. |
| 99 | +
|
| 100 | + Returns the fraction of regions imaged by the servicer, where regions are defined by |
| 101 | + the inspection points closest to each region center. |
| 102 | +
|
| 103 | + Args: |
| 104 | + servicer: The servicer satellite. |
| 105 | + chief: The chief satellite. |
| 106 | + region_centers: The centers of the regions to return inspection metrics for. |
| 107 | + It may be useful to set this as :class:`fibonacci_sphere` points. |
| 108 | + frame: The frame to use for the region centers. Can be ``chief_hill`` or |
| 109 | + ``chief_body``. |
| 110 | + """ |
| 111 | + assert frame in ["chief_hill", "chief"] |
| 112 | + point_inspect_status = servicer.data_store.data.point_inspect_status |
| 113 | + |
| 114 | + region_centers_C = [] |
| 115 | + for region_center in region_centers: |
| 116 | + if frame == "chief_hill": |
| 117 | + HN = rv2HN(chief.dynamics.r_BN_N, chief.dynamics.v_BN_N) |
| 118 | + CN = MRP2C(chief.dynamics.sigma_BN) |
| 119 | + region_center_C = CN @ HN.T @ region_center |
| 120 | + elif frame == "chief_body": |
| 121 | + region_center_C = region_center |
| 122 | + |
| 123 | + region_centers_C.append(region_center_C) |
| 124 | + |
| 125 | + imaged = np.zeros(len(region_centers)) |
| 126 | + total = np.zeros(len(region_centers)) |
| 127 | + for point, inspected in point_inspect_status.items(): |
| 128 | + # find the closest region center |
| 129 | + i_closest = np.argmin(np.linalg.norm(region_centers_C - point.r_PB_B, axis=1)) |
| 130 | + total[i_closest] += 1 |
| 131 | + if inspected: |
| 132 | + imaged[i_closest] += 1 |
| 133 | + |
| 134 | + return imaged / total |
| 135 | + |
| 136 | + |
89 | 137 | class RelativeProperties(Observation): |
90 | 138 | """Add arbitrary properties relative to some other satellite.""" |
91 | 139 |
|
@@ -185,4 +233,5 @@ def get_obs(self) -> dict[str, Any]: |
185 | 233 | "sigma_DHc", |
186 | 234 | "sigma_HdC", |
187 | 235 | "sigma_HdHc", |
| 236 | + "rso_imaged_regions", |
188 | 237 | ] |
0 commit comments