def soft_estop(self): # Stop Moving utils.publish_data_constant(self.pub_pos_enable, utils.get_axes(), False) utils.publish_data_constant(self.pub_power, utils.get_axes(), 0) self.powers = None self.last_powers = None self.pose = None
def run(self): rate = rospy.Rate(self.REFRESH_HZ) warned = False event_id = 0 while not rospy.is_shutdown(): rate.sleep() if (self.pose and self.twist) or (self.pose and self.power) or ( self.twist and self.power): # More than one seen in one update cycle, so warn and continue rospy.logerr( "===> Controls received conflicting desired states! Halting robot. <===" ) self.soft_estop() continue elif not self.pose and not self.twist and not self.power: self.soft_estop() if not warned: rospy.logwarn(bcolors.WARN + ( "===> Controls received no desired state! Halting robot. " "(Event %d) <===" % event_id) + bcolors.RESET) warned = True continue # Now we have either pose XOR powers if warned: rospy.loginfo(bcolors.OKGREEN + ( "===> Controls now receiving desired state (End event %d) <===" % (event_id)) + bcolors.RESET) event_id += 1 warned = False if self.pose: self.enable_loops() utils.publish_data_dictionary(self.pub_pos, utils.get_axes(), self.pose) self.pose = None elif self.twist: self.enable_loops() self.disable_pos_loop() utils.publish_data_dictionary(self.pub_vel, utils.get_axes(), self.twist) self.twist = None elif self.power: self.disable_loops() # Enable stabilization on all axes with 0 power input for p in self.power.keys(): if self.power[p] == 0: utils.publish_data_constant(self.pub_vel_enable, [p], True) # Publish velocity setpoints to all Velocity loops, even though some are not enabled utils.publish_data_dictionary(self.pub_vel, utils.get_axes(), self.power) utils.publish_data_dictionary(self.pub_power, utils.get_axes(), self.power) self.power = None
def soft_estop(self): # Stop Moving self.disable_loops() utils.publish_data_constant(self.pub_control_effort, utils.get_axes(), 0) self.twist = None self.pose = None self.power = None
def run(self): rospy.init_node('desired_state') rate = rospy.Rate(self.REFRESH_HZ) warned = False event_id = 0 while not rospy.is_shutdown(): rate.sleep() if self.pose and self.powers: # More than one seen in one update cycle, so warn and continue rospy.logerr("===> Controls received both position and power! Halting robot. <===") self.soft_estop() continue elif not self.pose and not self.powers: self.soft_estop() if not warned: rospy.logwarn(bcolors.WARN + ("===> Controls received neither position nor power! Halting robot. (Event %d) <===" % event_id) + bcolors.RESET) warned = True continue # Now we have either pose XOR powers if warned: rospy.loginfo(bcolors.OKGREEN + ("===> Controls now receiving %s (End event %d) <===" % ("position" if self.pose else "powers", event_id)) + bcolors.RESET) event_id += 1 warned = False if self.pose: self.enable_loops() utils.publish_data_dictionary(self.pub_pos, utils.get_axes(), self.pose) self.pose = None elif self.powers: if self.last_powers is None or self.powers != self.last_powers: self.enable_loops() # Hold Position on the current state self.hold = dict(self.state) self.last_powers = dict(self.powers) # Nonzero entries bypass PID # If any nonzero xy power, disable those position pid loops if self.powers['x'] != 0 or self.powers['y'] != 0: utils.publish_data_constant(self.pub_pos_enable, ['x', 'y'], False) # If any nonzero rpy power, disable those position pid loops elif self.powers['roll'] != 0 or self.powers['pitch'] != 0 or self.powers['yaw'] != 0: utils.publish_data_constant(self.pub_pos_enable, ['roll', 'pitch', 'yaw'], False) # If any nonzero z power, disable those position pid loops if self.powers['z'] != 0: utils.publish_data_constant(self.pub_pos_enable, ['z'], False) # TODO: BOTH cases utils.publish_data_dictionary(self.pub_power, utils.get_axes(), self.powers) # Publish current state to the desired state for PID utils.publish_data_dictionary(self.pub_pos, utils.get_axes(), self.hold) self.powers = None
def enable_loops(self): # Enable all PID Loops utils.publish_data_constant(self.pub_pos_enable, utils.get_axes(), True)
def disable_pos_loop(self): # Disable position loop utils.publish_data_constant(self.pub_pos_enable, utils.get_axes(), False)
def disable_loops(self): utils.publish_data_constant(self.pub_pos_enable, utils.get_axes(), False) utils.publish_data_constant(self.pub_vel_enable, utils.get_axes(), False)