Exemple #1
0
    def __handle_move_head(self, command: sml.Identifier):
        """
        Handle a Soar move-head action.

        The Soar output should look like:
        (I3 ^move-head Vx)
          (Vx ^angle [ang])
        where [ang] is a real number in the range [-0.44, 0.78]. This command moves the head to the
        the given angle, where 0 is looking straight ahead and the angle is degrees from that
        position.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            angle = float(command.GetParameterValue("angle"))
        except ValueError as e:
            print("Invalid angle format {}".format(
                command.GetParameterValue("angle")))
            return False

        print("Moving head {}".format(angle))
        set_head_angle_action = self.robot.set_head_angle(degrees(angle),
                                                          in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return set_head_angle_action, status_wme
Exemple #2
0
    def __handle_move_lift(self, command: sml.Identifier):
        """
        Handle a Soar move-lift action.

        The Soar output should look like:
        (I3 ^move-lift Vx)
          (Vx ^height [hgt])
        where [hgt] is a real number in the range [0, 1]. This command moves the lift to the
        the given height, where 0 is the lowest possible position and 1 is the highest.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            height = float(command.GetParameterValue("height"))
        except ValueError as e:
            print("Invalid height format {}".format(
                command.GetParameterValue("height")))
            return False

        print("Moving lift {}".format(height))
        set_lift_height_action = self.robot.set_lift_height(height,
                                                            in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return set_lift_height_action, status_wme
Exemple #3
0
    def __handle_turn_to_face(self, command: sml.Identifier):
        """
        Handle a Soar turn-to-face action.

        The Soar output should look like:
        (I3 ^turn-to-face Vx)
          (Vx ^face-id [fid])
        where [fid] is the integer ID associated with the face to turn towards.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            fid = int(command.GetParameterValue("face-id"))
        except ValueError as e:
            print("Invalid face id format {}".format(
                command.GetParameterValue("face-id")))
            return False
        if fid not in self.faces.keys():
            print("Face {} not recognized".format(fid))
            return False

        print("Turning to face {}".format(fid))
        target_face = self.faces[fid]
        turn_towards_face_action = self.r.turn_towards_face(target_face,
                                                            in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return turn_towards_face_action, status_wme
Exemple #4
0
    def __handle_pick_up_object(self, command: sml.Identifier):
        """
        Handle a Soar pick-up-object action.

        The Sour output should look like:
        (I3 ^pick-up-object Vx)
          (Vx ^object-id [id])
        where [id] is the object id of the object to pick up. Cozmo will approach the object
        autonomously and try to grasp it with its lift, then lift the lift up. This action is
        partiularly prone to failing.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            target_id = int(command.GetParameterValue("object-id"))
        except ValueError as e:
            print("Invalid object-id format {}".format(
                command.GetParameterValue("object-id")))
            return False

        obj_designation = "obj{}".format(target_id)
        if not self.objects.get(obj_designation):
            print("Couldn't find target object")
            return False

        print("Picking up object {}".format(obj_designation))
        target_obj = self.objects[obj_designation]
        pick_up_object_action = self.robot.pickup_object(target_obj,
                                                         in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return pick_up_object_action, status_wme
Exemple #5
0
    def __handle_dock_with_cube(self, command: sml.Identifier):
        """
        Handle a Soar dock-with-cube action.

        The Sour output should look like:
        (I3 ^dock-with-cube Vx)
          (Vx ^object-id [id])
        where [id] is the object id of the cube to dock with. Cozmo will approach the cube until
        its lift hooks are under the grip holes.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            target_id = int(command.GetParameterValue("object-id"))
            target_id = "obj{}".format(target_id)
        except ValueError as e:
            print("Invalid target-object-id format {}".format(
                command.GetParameterValue("object-id")))
            return False
        if target_id not in self.objects.keys():
            print("Couldn't find target object")
            return False

        print("Docking with cube with object id {}".format(target_id))
        target_obj = self.objects[target_id]
        dock_with_cube_action = self.robot.dock_with_cube(target_obj,
                                                          in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return dock_with_cube_action, status_wme
Exemple #6
0
    def __handle_place_on_object(self, command: sml.Identifier):
        """
        Handle a Soar place-on-object action.

        The Sour output should look like:
        (I3 ^place-on-object Vx)
          (Vx ^object-id [id])
        where [id] is the object id of the object that Cozmo should place to object its holding
        on top of.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            target_id = int(command.GetParameterValue("object-id"))
        except ValueError as e:
            print("Invalid object-id format {}".format(
                command.GetParameterValue("object-id")))
            return False

        target_dsg = "obj{}".format(target_id)
        if target_dsg not in self.objects.keys():
            print("Couldn't find target object")
            print(self.objects)
            return False

        print("Placing held object on top of {}".format(target_dsg))
        target_obj = self.objects[target_dsg]
        place_on_object_action = self.robot.place_on_object(target_obj,
                                                            in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return place_on_object_action, status_wme
Exemple #7
0
    def __handle_set_backpack_lights(self, command: sml.Identifier):
        """
        Handle a Soar set-backpack-lights action.

        The Sour output should look like:
        (I3 ^set-backpack-lights Vx)
          (Vx ^color [color])
        where [color] is a string indicating which color the lights should be set to. The colors
        are "red", "blue", "green", "white", and "off".

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        color_str = command.GetParameterValue("color")
        if color_str not in COLORS:
            print("Invalid backpack lights color {}".format(color_str))
            return False
        elif color_str == "red":
            light = cozmo.lights.red_light
        elif color_str == "green":
            light = cozmo.lights.green_light
        elif color_str == "blue":
            light = cozmo.lights.blue_light
        elif color_str == "white":
            light = cozmo.lights.white_light
        else:
            light = cozmo.lights.off_light

        self.r.set_all_backpack_lights(light=light)
        command.AddStatusComplete()
        return (None, None)
Exemple #8
0
    def __handle_change_block_color(self, command: sml.Identifier):
        """
        Handle a Soar change-block-color command.

        The Soar output should look like:
        (I3 ^change-block-color Vx)
            (Vx ^color [str]
                ^object-id [id])
        where color is the color name to change to from the valid colors and id
        is the object-id of the cube which should have its color changed.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            target_id = int(command.GetParameterValue("object-id"))
        except ValueError as e:
            #TODO: Update action WME to have failure codes
            print("Invalid object-id format, must be int")
            return False
        if f"obj{target_id}" not in self.objects.keys():
            #TODO: Update action WME to have failure codes
            print(f"Invalid object-id {target_id}, can't find it")
            return False

        color = command.GetParameterValue("color").lower()
        if color not in COLORS:
            print(f"Invalid color choice: {color}")
            status_wme = psl.SoarWME("status", "failed")
            fail_code_wme = psl.SoarWME("failure-code", "invalid-color")
            fail_reason_wme = psl.SoarWME("failure-reason",
                                          "invalid-color: {}".format(color))
            status_wme.add_to_wm(command)
            fail_code_wme.add_to_wm(command)
            fail_reason_wme.add_to_wm(command)
            status_wme.update_wm()
            return False

        print(f"Changing object {target_id} to color {color}")
        target_block = self.objects[f"obj{target_id}"]
        print("Target object: {}".format(target_block.cube_id))
        target_block.set_lights_off()
        target_block.set_lights(LIGHTS_DICT[color])
        status_wme = psl.SoarWME("status", "complete")
        status_wme.add_to_wm(command)
        status_wme.update_wm()
        return (None, None)
Exemple #9
0
    def __handle_go_to_object(self, command: sml.Identifier):
        """
        Handle a Soar go-to-object action.

        The Sour output should look like:
        (I3 ^go-to-object Vx)
          (Vx ^object-id [id]
              ^distance [dist])
        where [id] is the object id of the object to go to and [dist] indicates
        how far to stop from the object in mm. Only works on LightCubes.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            target_id = int(command.GetParameterValue("object-id"))
            target_id = f"obj{target_id}"
        except ValueError as e:
            print("Invalid target-object-id format {}".format(
                command.GetParameterValue("object-id")))
            return False
        if target_id not in self.objects.keys():
            print("Couldn't find target object")
            return False

        try:
            distance = distance_mm(float(
                command.GetParameterValue("distance")))
        except ValueError as e:
            print("Invalid distance format {}".format(
                command.GetParameterValue("distance")))
            return False

        print("Going to object {}".format(target_id))
        target_obj = self.objects[target_id]
        go_to_object_action = self.robot.go_to_object(target_obj,
                                                      distance,
                                                      in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return go_to_object_action, status_wme
Exemple #10
0
    def __handle_drive_forward(self, command: sml.Identifier):
        """
        Handle a Soar drive-forward action.

        The Sour output should look like:
        (I3 ^drive-forward Vx)
          (Vx ^distance [dist]
              ^speed [spd])
        where [dist] is a real number indicating how far Cozmo should travel (negatives go
        backwards) and speed is how fast Cozmo should travel. Units are mm and mm/s, respectively.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            distance = distance_mm(float(
                command.GetParameterValue("distance")))
        except ValueError as e:
            print("Invalid distance format {}".format(
                command.GetParameterValue("distance")))
            return False
        try:
            speed = speed_mmps(float(command.GetParameterValue("speed")))
        except ValueError as e:
            print("Invalid speed format {}".format(
                command.GetParameterValue("speed")))
            return False

        print("Driving forward {}mm at {}mm/s".format(distance.distance_mm,
                                                      speed.speed_mmps))
        drive_forward_action = self.r.drive_straight(distance,
                                                     speed,
                                                     in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return drive_forward_action, status_wme
Exemple #11
0
    def __handle_turn_in_place(self, command: sml.Identifier):
        """
        Handle a Soar turn-in-place action.

        The Sour output should look like:
        (I3 ^turn-in-place Vx)
          (Vx ^angle [ang]
              ^speed [spd])
        where [ang] is the amount Cozmo should rotate in degrees and speed is the speed at which
        Cozmo should rotate in deg/s.

        :param command: Soar command object
        :return: True if successful, False otherwise
        """
        try:
            angle = degrees(float(command.GetParameterValue("angle")))
        except ValueError as e:
            print("Invalid angle format {}".format(
                command.GetParameterValue("angle")))
            return False
        try:
            speed = degrees(float(command.GetParameterValue("speed")))
        except ValueError as e:
            print("Invalid speed format {}".format(
                command.GetParameterValue("speed")))
            return False

        print("Rotating in place {} degrees at {}deg/s".format(
            angle.degrees, speed.degrees))
        turn_in_place_action = self.r.turn_in_place(angle=angle,
                                                    speed=speed,
                                                    in_parallel=True)
        status_wme = psl.SoarWME("status", "running")
        status_wme.add_to_wm(command)
        status_wme.update_wm()

        return turn_in_place_action, status_wme