Skip to content

Module pyastrobee.config.iss_safe_boxes

Description of the free space within the ISS as a collection of safe boxes

View Source
"""Description of the free space within the ISS as a collection of safe boxes"""

from pyastrobee.config.astrobee_geom import COLLISION_RADIUS

from pyastrobee.utils.boxes import Box, visualize_3D_box, compute_graph, contract_box

from pyastrobee.utils.algos import dfs

# TODO:

# Test cases:

# - Avoid 3-way intersections

# - Ensure that the graph is connected

# (Run these tests when accounting for the collision radius of the Astrobee)

# Names of the safe boxes in the ISS

# Originally these were an enum but this made indexing in the graph search weird

# Strings are easier so we'll assign them to constants here just for reduced chance of error

JPM = "jpm"

NODE_2 = "node_2"

EU_LAB = "eu_lab"

US_LAB = "us_lab"

NODE_1 = "node_1"

# Node 3 has two boxes since there is a toilet blocking an area

NODE_3_A = "node_3_a"

NODE_3_B = "node_3_b"

CUPOLA = "cupola"

# Corridors between modules

JPM_N2_CORRIDOR = "jpm_n2_corridor"

N2_EU_CORRIDOR = "n2_eu_corridor"

N2_US_CORRIDOR = "n2_us_corridor"

US_N1_CORRIDOR = "us_n1_corridor"

N1_N3_CORRIDOR = "n1_n3_corridor"

N3_CUPOLA_CORRIDOR = "n3_cupola_corridor"

# Full description of free space within the ISS (Manually calibrated from simulation)

FULL_SAFE_SET = {

    JPM: Box([3.200, -0.775, -1.000], [10.500, 0.912, 1.000]),

    NODE_2: Box([-1.000, -2.458, -1.100], [1.100, 1.091, 0.924]),

    EU_LAB: Box([-7.703, -0.866, -1.000], [-3.400, 0.925, 1.000]),

    US_LAB: Box([-1.000, -11.265, -1.000], [0.874, -5.806, 1.000]),

    NODE_1: Box([-0.952, -17.165, -1.000], [1.000, -13.449, 1.028]),

    NODE_3_A: Box([2.900, -15.589, -1.000], [6.322, -14.700, 0.588]),

    NODE_3_B: Box([4.958, -15.53, -1.000], [7.646, -14.107, 0.939]),

    CUPOLA: Box([5.900, -15.18, 1.367], [6.662, -14.285, 3.158]),

    JPM_N2_CORRIDOR: Box([0.100, -0.475, -0.600], [4.800, 0.475, 0.600]),

    N2_EU_CORRIDOR: Box([-4.800, -0.475, -0.600], [-0.100, 0.475, 0.600]),

    N2_US_CORRIDOR: Box([-0.600, -6.902, -0.600], [0.600, -1.348, 0.600]),

    US_N1_CORRIDOR: Box([-0.600, -14.350, -0.600], [0.600, -10.200, 0.600]),

    N1_N3_CORRIDOR: Box([-0.100, -15.400, -0.600], [4.18, -14.400, 0.600]),

    N3_CUPOLA_CORRIDOR: Box([5.800, -15.421, 0.119], [7.000, -14.100, 2.179]),

}

# Locations where the robot base can travel (the full safe set but shrunk by the collision radius)

ROBOT_SAFE_SET = {

    module: contract_box(box, COLLISION_RADIUS)

    for (module, box) in FULL_SAFE_SET.items()

}

def compute_iss_graph() -> dict[str, list[str]]:

    """Computes the graph between the safe sets in the ISS based on intersecting safe boxes

    Returns:

        dict[str, list[str]]: Adjacency list / graph dictating safe paths in the ISS. Key/value pair is:

            (name of the module) -> (list of names of all neighbors of that module)

    """

    # Use the robot safe set here because it gives a better description of motion

    # If we use the full safe set there could be some locations with 3-way intersections that don't present themselves

    # when planning for working with the robot

    return compute_graph(ROBOT_SAFE_SET)

def _show_iss_boxes():

    """Visualize the safe set in Pybullet"""

    import pybullet  # pylint: disable=import-outside-toplevel

    pybullet.connect(pybullet.GUI)

    for box in FULL_SAFE_SET.values():

        visualize_3D_box(box, rgba=(1, 0, 0, 0.5))

    for box in ROBOT_SAFE_SET.values():

        visualize_3D_box(box, rgba=(0, 0, 1, 0.5))

    input("Press Enter to exit")

    pybullet.disconnect()

def _test_graph_search():

    """Example of computing the path between boxes in the ISS"""

    graph = compute_iss_graph()

    start = JPM

    end = CUPOLA

    path = dfs(graph, start, end)

    print(f"Box sequence between {start} and {end}: ")

    print(path)

if __name__ == "__main__":

    _test_graph_search()

    _show_iss_boxes()

Variables

COLLISION_RADIUS
CUPOLA
EU_LAB
FULL_SAFE_SET
JPM
JPM_N2_CORRIDOR
N1_N3_CORRIDOR
N2_EU_CORRIDOR
N2_US_CORRIDOR
N3_CUPOLA_CORRIDOR
NODE_1
NODE_2
NODE_3_A
NODE_3_B
ROBOT_SAFE_SET
US_LAB
US_N1_CORRIDOR

Functions

compute_iss_graph

def compute_iss_graph(

) -> dict[str, list[str]]

Computes the graph between the safe sets in the ISS based on intersecting safe boxes

Returns:

Type Description
dict[str, list[str]] Adjacency list / graph dictating safe paths in the ISS. Key/value pair is:
(name of the module) -> (list of names of all neighbors of that module)
View Source
def compute_iss_graph() -> dict[str, list[str]]:

    """Computes the graph between the safe sets in the ISS based on intersecting safe boxes

    Returns:

        dict[str, list[str]]: Adjacency list / graph dictating safe paths in the ISS. Key/value pair is:

            (name of the module) -> (list of names of all neighbors of that module)

    """

    # Use the robot safe set here because it gives a better description of motion

    # If we use the full safe set there could be some locations with 3-way intersections that don't present themselves

    # when planning for working with the robot

    return compute_graph(ROBOT_SAFE_SET)