示例#1
0
    def __init__(self, controller_name, wrench_pub=None):
        self.name = controller_name
        self.wrench_choices = itertools.cycle(
            ["rc", "emergency", "keyboard", "autonomous"])

        self.kill_broadcaster = AlarmBroadcaster('kill')
        self.station_hold_broadcaster = AlarmBroadcaster('station-hold')

        self.wrench_changer = rospy.ServiceProxy("/wrench/select", MuxSelect)
        self.task_client = MissionClient()
        self.kill_listener = AlarmListener(
            'kill', callback_funct=self._update_kill_status)

        if (wrench_pub is None):
            self.wrench_pub = wrench_pub
        else:
            self.wrench_pub = rospy.Publisher(wrench_pub,
                                              WrenchStamped,
                                              queue_size=1)

        self.shooter_load_client = actionlib.SimpleActionClient(
            "/shooter/load", ShooterDoAction)
        self.shooter_fire_client = actionlib.SimpleActionClient(
            "/shooter/fire", ShooterDoAction)
        self.shooter_cancel_client = rospy.ServiceProxy(
            "/shooter/cancel", Trigger)
        self.shooter_manual_client = rospy.ServiceProxy(
            "/shooter/manual", ShooterManual)
        self.shooter_reset_client = rospy.ServiceProxy("/shooter/reset",
                                                       Trigger)

        self.is_killed = False
        self.is_timed_out = False
        self.clear_wrench()
示例#2
0
文件: kill.py 项目: uf-mil/mil
 def __init__(self):
     self._killed = False
     self.initial_alarm = Alarm(self.alarm_name, True,
                                node_name='alarm_server',
                                problem_description='Initial kill')
     self.bag_client = SimpleActionClient("/online_bagger/bag", BagOnlineAction)
     self.task_client = MissionClient()
     self.first = True
示例#3
0
文件: kill.py 项目: uf-mil/mil
class Kill(HandlerBase):
    alarm_name = 'kill'

    def __init__(self):
        self._killed = False
        self.initial_alarm = Alarm(self.alarm_name, True,
                                   node_name='alarm_server',
                                   problem_description='Initial kill')
        self.bag_client = SimpleActionClient("/online_bagger/bag", BagOnlineAction)
        self.task_client = MissionClient()
        self.first = True

    def _online_bagger_cb(self, status, result):
        if status == 3:
            rospy.loginfo('KILL BAG WRITTEN TO {}'.format(result.filename))
        else:
            rospy.logwarn('KILL BAG {}, status: {}'.format(TerminalState.to_string(status), result.status))

    def _kill_task_cb(self, status, result):
        if status == 3:
            rospy.loginfo('Killed task success!')
            return
        rospy.logwarn('Killed task failed ({}): {}'.format(TerminalState.to_string(status), result.result))

    def raised(self, alarm):
        self._killed = True
        if self.first:
            self.first = False
            return
        if 'BAG_ALWAYS' not in os.environ or 'bag_kill' not in os.environ:
            rospy.logwarn('BAG_ALWAYS or BAG_KILL not set. Not making kill bag.')
        else:
            goal = BagOnlineGoal(bag_name='kill.bag')
            goal.topics = os.environ['BAG_ALWAYS'] + ' ' + os.environ['bag_kill']
            self.bag_client.send_goal(goal, done_cb=self._online_bagger_cb)
        self.task_client.run_mission('Killed', done_cb=self._kill_task_cb)

    def cleared(self, alarm):
        self._killed = False

    def meta_predicate(self, meta_alarm, alarms):
        ignore = []

        # Don't kill on low battery, only on critical
        # if alarms['battery-voltage'].raised and alarms['battery-voltage'].severity < 2:
        #     ignore.append('battery-voltage')

        # Raised if any alarms besides the two above are raised
        raised = [name for name, alarm in alarms.items() if name not in ignore and alarm.raised]
        if len(raised):
            return Alarm('kill', True, node_name=rospy.get_name(),
                         problem_description='Killed by meta alarm(s) ' + ', '.join(raised),
                         parameters={'Raised': raised})
        return self._killed
示例#4
0
class RunMissionTest(unittest.TestCase):
    def __init__(self, *args):
        self.client = MissionClient()
        self.client.wait_for_server()
        super(RunMissionTest, self).__init__(*args)

    def test_run_mission(self):
        self.client.run_mission('PrintAndWait')
        self.client.wait_for_result()
        result = self.client.get_result()
        state = self.client.get_state()
        self.assertEqual(state, TerminalState.SUCCEEDED)
        self.assertTrue(result.success)
        self.assertEqual(result.parameters, '')
        self.assertEqual(result.result, 'The darkness isnt so scary')
class RunMissionTest(unittest.TestCase):
    def __init__(self, *args):
        self.client = MissionClient()
        self.client.wait_for_server()
        super(RunMissionTest, self).__init__(*args)

    def test_run_mission(self):
        self.client.run_mission('PrintAndWait')
        self.client.wait_for_result()
        result = self.client.get_result()
        state = self.client.get_state()
        self.assertEqual(state, TerminalState.SUCCEEDED)
        self.assertTrue(result.success)
        self.assertEqual(result.parameters, '')
        self.assertEqual(result.result, 'The darkness isnt so scary')
示例#6
0
class StationHold(HandlerBase):
    alarm_name = 'station-hold'

    def __init__(self):
        self.task_client = MissionClient()
        self.broadcaster = AlarmBroadcaster(self.alarm_name)

    def _client_cb(self, terminal_state, result):
        if terminal_state != 3:
            rospy.logwarn(
                'Station hold goal failed (Status={}, Result={})'.format(
                    TerminalState.to_string(terminal_state), result.result))
            return
        rospy.loginfo('Station holding!')
        self.broadcaster.clear_alarm()

    def raised(self, alarm):
        rospy.loginfo("Attempting to station hold")
        self.task_client.run_mission('StationHold', done_cb=self._client_cb)

    def cleared(self, alarm):
        # When cleared, do nothing and just wait for new goal / custom wrench
        pass
示例#7
0
 def __init__(self, *args):
     self.client = MissionClient()
     self.client.wait_for_server()
     super(RunMissionTest, self).__init__(*args)
示例#8
0
class RemoteControl(object):
    def __init__(self, controller_name, wrench_pub=None):
        self.name = controller_name
        self.wrench_choices = itertools.cycle(
            ["rc", "emergency", "keyboard", "autonomous"])

        self.kill_broadcaster = AlarmBroadcaster('kill')
        self.station_hold_broadcaster = AlarmBroadcaster('station-hold')

        self.wrench_changer = rospy.ServiceProxy("/wrench/select", MuxSelect)
        self.task_client = MissionClient()
        self.kill_listener = AlarmListener(
            'kill', callback_funct=self._update_kill_status)

        if (wrench_pub is None):
            self.wrench_pub = wrench_pub
        else:
            self.wrench_pub = rospy.Publisher(wrench_pub,
                                              WrenchStamped,
                                              queue_size=1)

        self.shooter_load_client = actionlib.SimpleActionClient(
            "/shooter/load", ShooterDoAction)
        self.shooter_fire_client = actionlib.SimpleActionClient(
            "/shooter/fire", ShooterDoAction)
        self.shooter_cancel_client = rospy.ServiceProxy(
            "/shooter/cancel", Trigger)
        self.shooter_manual_client = rospy.ServiceProxy(
            "/shooter/manual", ShooterManual)
        self.shooter_reset_client = rospy.ServiceProxy("/shooter/reset",
                                                       Trigger)

        self.is_killed = False
        self.is_timed_out = False
        self.clear_wrench()

    def _timeout_check(function):
        '''
        Simple decorator to check whether or not the remote control device is
        timed out before running the function that was called.
        '''
        @functools.wraps(function)
        def wrapper(self, *args, **kwargs):
            if (not self.is_timed_out):
                return function(self, *args, **kwargs)

        return wrapper

    def _update_kill_status(self, alarm):
        '''
        Updates the kill status display when there is an update on the kill
        alarm.
        '''
        self.is_killed = alarm.raised

    @_timeout_check
    def kill(self, *args, **kwargs):
        '''
        Kills the system regardless of what state it is in.
        '''
        rospy.loginfo("Killing")
        self.kill_broadcaster.raise_alarm(
            problem_description="System kill from user remote control",
            parameters={'location': self.name})

    @_timeout_check
    def clear_kill(self, *args, **kwargs):
        '''
        Clears the system kill regardless of what state it is in.
        '''
        rospy.loginfo("Reviving")
        self.kill_broadcaster.clear_alarm()

    @_timeout_check
    def toggle_kill(self, *args, **kwargs):
        '''
        Toggles the kill status when the toggle_kill_button is pressed.
        '''
        rospy.loginfo("Toggling Kill")

        # Responds to the kill broadcaster and checks the status of the kill alarm
        if self.is_killed:
            self.kill_broadcaster.clear_alarm()
        else:
            self.kill_broadcaster.raise_alarm(
                problem_description="System kill from user remote control",
                parameters={'location': self.name})

    @_timeout_check
    def station_hold(self, *args, **kwargs):
        '''
        Sets the goal point to the current location and switches to autonomous
        mode in order to stay at that point.
        '''
        rospy.loginfo("Station Holding")

        # Trigger station holding at the current pose
        self.station_hold_broadcaster.raise_alarm(
            problem_description="Request to station hold from remote control",
            parameters={'location': self.name})

    @_timeout_check
    def deploy_thrusters(self, *args, **kwargs):
        def cb(terminal_state, result):
            if terminal_state == 3:
                rospy.loginfo('Thrusters Deployed!')
            else:
                rospy.logwarn(
                    'Error deploying thrusters: {}, status: {}'.format(
                        TerminalState.to_string(terminal_state),
                        result.status))

        self.task_client.run_task('DeployThrusters', done_cb=cb)

    @_timeout_check
    def retract_thrusters(self, *args, **kwargs):
        def cb(terminal_state, result):
            if terminal_state == 3:
                rospy.loginfo('Thrusters Retracted!')
            else:
                rospy.logwarn(
                    'Error rectracting thrusters: {}, status: {}'.format(
                        TerminalState.to_string(terminal_state),
                        result.status))

        self.task_client.run_task('RetractThrusters', done_cb=cb)

    @_timeout_check
    def select_autonomous_control(self, *args, **kwargs):
        '''
        Selects the autonomously generated trajectory as the active controller.
        '''
        rospy.loginfo("Changing Control to Autonomous")
        self.wrench_changer("autonomous")

    @_timeout_check
    def select_rc_control(self, *args, **kwargs):
        '''
        Selects the XBox remote joystick as the active controller.
        '''
        rospy.loginfo("Changing Control to RC")
        self.wrench_changer("rc")

    def select_emergency_control(self, *args, **kwargs):
        '''
        Selects the emergency controller as the active controller.
        '''
        rospy.loginfo("Changing Control to Emergency Controller")
        self.wrench_changer("emergency")

    @_timeout_check
    def select_keyboard_control(self, *args, **kwargs):
        '''
        Selects the keyboard teleoperation service as the active controller.
        '''
        rospy.loginfo("Changing Control to Keyboard")
        self.wrench_changer("keyboard")

    @_timeout_check
    def select_next_control(self, *args, **kwargs):
        '''
        Selects the autonomously generated trajectory as the active controller.
        '''
        mode = next(self.wrench_choices)
        rospy.loginfo("Changing Control Mode: {}".format(mode))
        self.wrench_changer(mode)

    def _shooter_load_feedback(self, status, result):
        '''
        Prints the feedback that is returned by the shooter load action client
        '''
        rospy.loginfo("Shooter Load Status={} Success={} Error={}".format(
            status, result.success, result.error))

    @_timeout_check
    def shooter_load(self, *args, **kwargs):
        '''
        Loads the shooter by using the action client to retract the linear actuator
        '''
        self.shooter_load_client.send_goal(goal=ShooterDoActionGoal(),
                                           done_cb=self._shooter_load_feedback)
        rospy.loginfo("Kip, do not throw away your shot.")

    def _shooter_fire_feedback(self, status, result):
        '''
        Prints the feedback that is returned by the shooter fire action client
        '''
        rospy.loginfo("Shooter Fire Status={} Success={} Error={}".format(
            status, result.success, result.error))

    @_timeout_check
    def shooter_fire(self, *args, **kwargs):
        '''
        Fires the shooter by using the action client to spin up the
        acceleration discs and extend the linear actuator.
        '''
        self.shooter_fire_client.send_goal(goal=ShooterDoActionGoal(),
                                           done_cb=self._shooter_fire_feedback)
        rospy.loginfo(
            "One, two, three, four, five, six, seven, eight, nine. Number... TEN PACES! FIRE!"
        )

    @_timeout_check
    def shooter_cancel(self, *args, **kwargs):
        '''
        Cancels the process that the shooter action client is currently
        running.
        '''
        rospy.loginfo("Canceling shooter requests")
        self.shooter_cancel_client(TriggerRequest())
        rospy.loginfo("I imaging death so much it feels more like a memory.")
        rospy.loginfo(
            "When's it gonna get me? While I'm blocked? Seven clocks ahead of me?"
        )

    def _shooter_reset_helper(self, event):
        '''
        Used to actually call the shooter's reset service.
        '''
        rospy.loginfo("Reseting the shooter service")
        self.shooter_reset_client(TriggerRequest())
        rospy.loginfo(
            "In New York you can be a new man! In New York you can be a new man!"
        )

    @_timeout_check
    def shooter_reset(self, *args, **kwargs):
        '''
        Ensures that the shooter is fully retracted by initiating a retract and
        using a ~6s delay before calling the actual reset service.
        '''
        self.shooter_linear_retract()
        rospy.Timer(rospy.Duration(6),
                    self._shooter_reset_helper,
                    oneshot=True)

    @_timeout_check
    def shooter_linear_extend(self, *args, **kwargs):
        '''
        Extends the shooter's linear actuator by setting it's speed to full
        forward
        '''
        rospy.loginfo("Extending the shooter's linear actuator")
        self.shooter_manual_client(1, 0)

    @_timeout_check
    def shooter_linear_retract(self, *args, **kwargs):
        '''
        Retracts the shooter's linear actuator by setting it's speed to full
        reverse
        '''
        rospy.loginfo("Retracting the shooter's linear actuator")
        self.shooter_manual_client(-1, 0)

    @_timeout_check
    def set_disc_speed(self, speed, *args, **kwargs):
        '''
        Sets the shooters disc speed to the speed value passed in. The value is
        a percentage from -100 to 100, which is scaled down to a number from -1
        to 1.
        '''
        rospy.loginfo(
            "Setting the shooter's accelerator disc speed to {}".format(speed))
        self.shooter_manual_client(0, float(speed) / -100)

    @_timeout_check
    def publish_wrench(self, x, y, rotation, stamp=None, *args, **kwargs):
        '''
        Publishes a wrench to the specified node based on force inputs from the
        controller.
        '''
        if (stamp is None):
            stamp = rospy.Time.now()

        if (self.wrench_pub is not None):
            wrench = WrenchStamped()
            wrench.header.frame_id = "/base_link"
            wrench.header.stamp = stamp
            wrench.wrench.force.x = x
            wrench.wrench.force.y = y
            wrench.wrench.torque.z = rotation
            self.wrench_pub.publish(wrench)

    @_timeout_check
    def clear_wrench(self, *args, **kwargs):
        '''
        Publishes a wrench to the specified node based on force inputs from the
        controller.
        '''
        if (self.wrench_pub is not None):
            wrench = WrenchStamped()
            wrench.header.frame_id = "/base_link"
            wrench.header.stamp = rospy.Time.now()
            wrench.wrench.force.x = 0
            wrench.wrench.force.y = 0
            wrench.wrench.torque.z = 0
            self.wrench_pub.publish(wrench)
示例#9
0
 def __init__(self):
     self.task_client = MissionClient()
     self.broadcaster = AlarmBroadcaster(self.alarm_name)
示例#10
0
 def __init__(self, *args):
     self.client = MissionClient()
     self.client.wait_for_server()
     super(RunMissionTest, self).__init__(*args)