|
11 | 11 | from software.thunderscope.gl.helpers.extended_gl_view_widget import MouseInSceneEvent |
12 | 12 | from software.thunderscope.proto_unix_io import ProtoUnixIO |
13 | 13 | from software.thunderscope.constants import Colors, DepthValues |
| 14 | +from software.py_constants import * |
14 | 15 |
|
15 | 16 |
|
16 | 17 | class Operation(ABC): |
@@ -410,11 +411,15 @@ def redo(self) -> None: |
410 | 411 | if not self.is_playing: |
411 | 412 | self._update_robots_graphics() |
412 | 413 |
|
413 | | - def clear_field(self) -> None: |
414 | | - """Removes all robots from the field. |
415 | | - Adds a GroupOperation to the undo list that can restore all robots. |
| 414 | + def __get_current_state_as_operation(self) -> GroupOperation: |
| 415 | + """Captures the current positions of all robots as a GroupOperation |
| 416 | + for undo purposes. Merges positions from both the cached world state and |
| 417 | + the local state into a single GroupOperation |
| 418 | + containing one RobotOperation per robot. |
| 419 | +
|
| 420 | + :return: a GroupOperation where each inner RobotOperation represents |
| 421 | + the current position of a friendly robot on the field |
416 | 422 | """ |
417 | | - # collect current robot positions into a GroupOperation for undo |
418 | 423 | operations = {} |
419 | 424 |
|
420 | 425 | # check the cached world state first |
@@ -449,9 +454,36 @@ def clear_field(self) -> None: |
449 | 454 | next_id=self.next_id, |
450 | 455 | ) |
451 | 456 |
|
452 | | - if operations: |
453 | | - self.undo_operations.append(GroupOperation(operations=operations.values())) |
454 | | - self.undo_toggle_enabled_signal.emit(len(self.undo_operations) != 0) |
| 457 | + return GroupOperation(operations=operations.values()) |
| 458 | + |
| 459 | + def clear_field(self) -> None: |
| 460 | + """Removes all robots from the field. |
| 461 | + Adds a GroupOperation to the undo list that can restore all robots. |
| 462 | + """ |
| 463 | + self.__clear_reset_helper(self.__get_clear_world_state) |
| 464 | + |
| 465 | + def reset_field(self) -> None: |
| 466 | + """Resets the robots on field to the default positions |
| 467 | + Adds a GroupOperation to the undo list that can restore all robots to their previous positions. |
| 468 | + """ |
| 469 | + self.__clear_reset_helper(self.__get_empty_world_state) |
| 470 | + |
| 471 | + def __clear_reset_helper( |
| 472 | + self, world_state_fn: Callable[[], SandboxWorldState] |
| 473 | + ) -> None: |
| 474 | + """Shared helper for clearing or resetting the field. |
| 475 | + Saves the current robot state as an undo operation, clears internal |
| 476 | + state (robot ids, local positions, and the redo stack), and sends |
| 477 | + an empty world state to the simulator. |
| 478 | +
|
| 479 | + :param world_state_fn: A callable that returns the new |
| 480 | + SandboxWorldState to send to the simulator after clearing |
| 481 | + internal state |
| 482 | + """ |
| 483 | + undo_operation = self.__get_current_state_as_operation() |
| 484 | + |
| 485 | + self.undo_operations.append(undo_operation) |
| 486 | + self.undo_toggle_enabled_signal.emit(len(self.undo_operations) != 0) |
455 | 487 |
|
456 | 488 | # clear internal state |
457 | 489 | self.curr_robot_ids.clear() |
@@ -531,33 +563,23 @@ def __undo_redo_internal(self, operation: Operation) -> None: |
531 | 563 | operation.id, operation.pos, self.DEFAULT_ROBOT_ANGLE, clear_redo=False |
532 | 564 | ) |
533 | 565 |
|
534 | | - def __get_empty_world_state(self) -> SandboxWorldState: |
535 | | - """Constructs a SandboxWorldState with just the ball state filled in |
536 | | - from the cached world state and 1 robot placed at |
537 | | - the edge of the center circle on the half line |
538 | | -
|
539 | | - Replaces all local states as well |
| 566 | + def __get_clear_world_state(self) -> SandboxWorldState: |
| 567 | + """Constructs a SandboxWorldState with the default ball position |
| 568 | + and no robots |
540 | 569 |
|
541 | | - :return: the sandbox world state with ball state and 1 robot |
| 570 | + :return: the sandbox world state with ball state and no robots |
542 | 571 | """ |
543 | | - world_state = GLSandboxWorldLayer.SandboxWorldState( |
544 | | - self.__invert_robot_if_defending_negative_half, self.friendly_colour_yellow |
545 | | - ) |
546 | | - world_state.set_ball_state(self.cached_world.ball.current_state) |
| 572 | + world_state = tbots_protobuf.create_default_world_state(0) |
547 | 573 |
|
548 | | - center_circle_radius = self.cached_world.field.center_circle_radius |
549 | | - robot_pos = QVector3D(-center_circle_radius, 0, 0) |
| 574 | + def __get_reset_world_state(self) -> SandboxWorldState: |
| 575 | + """Constructs a SandboxWorldState with the default ball position and |
| 576 | + the default number of robots in DIV B |
550 | 577 |
|
551 | | - for robot_id in self.local_robot_positions.keys(): |
552 | | - self.local_robot_positions[robot_id] = None |
553 | | - |
554 | | - world_state = self.__update_with_new_position( |
555 | | - world_state, self.MIN_ROBOT_ID, robot_pos, self.DEFAULT_ROBOT_ANGLE |
556 | | - ) |
| 578 | + This is the state that simulator always starts with |
557 | 579 |
|
558 | | - self.next_id = self.MIN_ROBOT_ID + 1 |
559 | | - |
560 | | - return world_state |
| 580 | + :return: the sandbox world state with ball state and DIV_B_NUM_ROBOTS robots |
| 581 | + """ |
| 582 | + world_state = tbots_protobuf.create_default_world_state(DIV_B_NUM_ROBOTS) |
561 | 583 |
|
562 | 584 | # # # # # # # # # # # # # # # # # # # # # # # # # |
563 | 585 | # ADD / REMOVE / MOVE ROBOT METHODS # |
|
0 commit comments