Skip to content

Sim Robot

SimRobot

Bases: Robot

A simulated robot interface for testing and validating purposes.

This class simulates the interface between the robot arm and the control system. do() simulates the execution of HandControl motions that got executed in execution_time.

Attributes:

Name Type Description
home_pos

The home position of the robot arm.

current_pos

The current position of the robot arm.

Source code in mbodied/robots/sim_robot.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class SimRobot(Robot):
    """A simulated robot interface for testing and validating purposes.

    This class simulates the interface between the robot arm and the control system.
    do() simulates the execution of HandControl motions that got executed in execution_time.

    Attributes:
        home_pos: The home position of the robot arm.
        current_pos: The current position of the robot arm.
    """

    def __init__(self, execution_time: float = 1.0):
        """Initializes the SimRobot and sets up the robot arm.

        Args:
            execution_time: The time it takes to execute a motion.

        position: [x, y, z, r, p, y, grasp]
        """
        self.execution_time = execution_time
        self.home_pos = [0, 0, 0, 0, 0, 0, 0]
        self.current_pos = self.home_pos

    def do(self, motion: HandControl | list[HandControl]) -> list[float]:
        """Executes HandControl motions and returns the new position of the robot arm.

        This simulates the execution of each motion for self.execution_time. It divides the motion into 10 steps.

        Args:
            motion: The HandControl motion to be executed.
        """
        if not isinstance(motion, list):
            motion = [motion]
        for m in motion:
            print("Executing motion:", m)  # noqa: T201

            # Number of steps to divide the motion into
            steps = 10
            sleep_duration = self.execution_time / steps
            step_motion = [value / steps for value in m.flatten()]
            for _ in range(steps):
                self.current_pos = [round(x + y, 5) for x, y in zip(self.current_pos, step_motion)]
                time.sleep(sleep_duration)

            print("New position:", self.current_pos)  # noqa: T201

        return self.current_pos

    def capture(self, **_) -> Image:
        """Captures an image."""
        resource = Path("resources") / "xarm.jpeg"
        return Image(resource, size=(224, 224))

    def get_observation(self) -> Image:
        """Alias of capture for recording."""
        return self.capture()

    def get_state(self) -> HandControl:
        """Gets the current pose of the robot arm.

        Returns:
            list[float]: A list of the current pose values [x, y, z, r, p, y, grasp].
        """
        return HandControl.unflatten(self.current_pos)

    def prepare_action(self, old_pose: HandControl, new_pose: HandControl) -> HandControl:
        """Calculates the action between two poses."""
        # Calculate the difference between the old and new poses. Use absolute value for grasp.
        old = list(old_pose.flatten())
        new = list(new_pose.flatten())
        result = [(new[i] - old[i]) for i in range(len(new) - 1)] + [new[-1]]
        return HandControl.unflatten(result)

__init__(execution_time=1.0)

Initializes the SimRobot and sets up the robot arm.

Parameters:

Name Type Description Default
execution_time float

The time it takes to execute a motion.

1.0

position: [x, y, z, r, p, y, grasp]

Source code in mbodied/robots/sim_robot.py
33
34
35
36
37
38
39
40
41
42
43
def __init__(self, execution_time: float = 1.0):
    """Initializes the SimRobot and sets up the robot arm.

    Args:
        execution_time: The time it takes to execute a motion.

    position: [x, y, z, r, p, y, grasp]
    """
    self.execution_time = execution_time
    self.home_pos = [0, 0, 0, 0, 0, 0, 0]
    self.current_pos = self.home_pos

capture(**_)

Captures an image.

Source code in mbodied/robots/sim_robot.py
70
71
72
73
def capture(self, **_) -> Image:
    """Captures an image."""
    resource = Path("resources") / "xarm.jpeg"
    return Image(resource, size=(224, 224))

do(motion)

Executes HandControl motions and returns the new position of the robot arm.

This simulates the execution of each motion for self.execution_time. It divides the motion into 10 steps.

Parameters:

Name Type Description Default
motion HandControl | list[HandControl]

The HandControl motion to be executed.

required
Source code in mbodied/robots/sim_robot.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def do(self, motion: HandControl | list[HandControl]) -> list[float]:
    """Executes HandControl motions and returns the new position of the robot arm.

    This simulates the execution of each motion for self.execution_time. It divides the motion into 10 steps.

    Args:
        motion: The HandControl motion to be executed.
    """
    if not isinstance(motion, list):
        motion = [motion]
    for m in motion:
        print("Executing motion:", m)  # noqa: T201

        # Number of steps to divide the motion into
        steps = 10
        sleep_duration = self.execution_time / steps
        step_motion = [value / steps for value in m.flatten()]
        for _ in range(steps):
            self.current_pos = [round(x + y, 5) for x, y in zip(self.current_pos, step_motion)]
            time.sleep(sleep_duration)

        print("New position:", self.current_pos)  # noqa: T201

    return self.current_pos

get_observation()

Alias of capture for recording.

Source code in mbodied/robots/sim_robot.py
75
76
77
def get_observation(self) -> Image:
    """Alias of capture for recording."""
    return self.capture()

get_state()

Gets the current pose of the robot arm.

Returns:

Type Description
HandControl

list[float]: A list of the current pose values [x, y, z, r, p, y, grasp].

Source code in mbodied/robots/sim_robot.py
79
80
81
82
83
84
85
def get_state(self) -> HandControl:
    """Gets the current pose of the robot arm.

    Returns:
        list[float]: A list of the current pose values [x, y, z, r, p, y, grasp].
    """
    return HandControl.unflatten(self.current_pos)

prepare_action(old_pose, new_pose)

Calculates the action between two poses.

Source code in mbodied/robots/sim_robot.py
87
88
89
90
91
92
93
def prepare_action(self, old_pose: HandControl, new_pose: HandControl) -> HandControl:
    """Calculates the action between two poses."""
    # Calculate the difference between the old and new poses. Use absolute value for grasp.
    old = list(old_pose.flatten())
    new = list(new_pose.flatten())
    result = [(new[i] - old[i]) for i in range(len(new) - 1)] + [new[-1]]
    return HandControl.unflatten(result)