diff --git a/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/base_hokuyo.launch b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/base_hokuyo.launch new file mode 100644 index 0000000000..e1c00a7a90 --- /dev/null +++ b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/base_hokuyo.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/check_hokuyo_scan_node.py b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/check_hokuyo_scan_node.py new file mode 100755 index 0000000000..e401697d6d --- /dev/null +++ b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/check_hokuyo_scan_node.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys,subprocess,traceback +import rospy +import time +import os +from sensor_msgs.msg import Image, CompressedImage, LaserScan +from sound_play.msg import SoundRequest, SoundRequestAction, SoundRequestGoal +import actionlib +import roslib + +class HokuyoScanChecker: + def __init__(self): + rospy.init_node('hokuyo_scan_checker_node', anonymous=True) + self.no_topic_flag = False ## True if topic is currently not coming in. + self.once_topic_flag = False ## True if the topic has been received at least once since the start of node execution. + + self.launch_process = None + self.hokuyo_name = rospy.get_param('~hokuyo_name', 'base') + + # Create an Action client for the sound_play node + self.sound_client = actionlib.SimpleActionClient('/robotsound', SoundRequestAction) + self.sound_client.wait_for_server() + + # Threshold (in seconds) when a topic is not updated for a certain period of time + self.timeout_threshold = 10.0 + + # Time the topic was last updated + self.last_image_time = time.time() + + self.say_something("{} scan check start".format(self.hokuyo_name)) + + # Subscribing topic + self.topic_sub = rospy.Subscriber('/{}_scan'.format(self.hokuyo_name), LaserScan, self.topic_callback) + + def topic_callback(self, msg): + # Callback to be called when topic is updated + self.last_image_time = time.time() + if self.no_topic_flag or self.once_topic_flag==False: + self.no_topic_flag = False + self.once_topic_flag = True + self.say_something("{} scan topic is arrive.".format(self.hokuyo_name)) + + def check_timeout(self): + # Check if the topic has not been updated for a certain period of time + if time.time() - self.last_image_time > self.timeout_threshold: + if self.no_topic_flag: + return + else: + self.no_topic_flag = True + self.say_something("I haven't seen the {} scan topic for {} seconds.".format(self.hokuyo_name, self.timeout_threshold)) + self.restart_hokuyo() + + def say_something(self, text): + # Let the robot talk + rospy.loginfo(text) + + # Create a SoundRequestGoal message + sound_goal = SoundRequestGoal() + sound_goal.sound_request.sound = SoundRequest.SAY + sound_goal.sound_request.command = SoundRequest.PLAY_ONCE + sound_goal.sound_request.volume = 1.0 + sound_goal.sound_request.arg = text + + # Send the SoundRequestGoal to the sound_play node + self.sound_client.send_goal(sound_goal) + + # Wait for the result (you can add timeout if needed) + self.sound_client.wait_for_result() + + def restart_hokuyo(self): + rospy.logerr("Restarting {} hokuyo".format(self.hokuyo_name)) + retcode = -1 + if self.launch_process: ## Force termination if launch process exists + self.launch_process.terminate() + self.launch_process.wait() + try: + # 1. kill hokuyo node + retcode = subprocess.call('rosnode kill /{}_hokuyo_node'.format(self.hokuyo_name), shell=True) + retcode = subprocess.call('pkill -f {}_hokuyo_node'.format(self.hokuyo_name), shell=True) + rospy.loginfo("Killed {} hokuyo node".format(self.hokuyo_name)) + time.sleep(10) + + # 2. reset hokuyo + package_path = roslib.packages.get_pkg_dir('jsk_pr2_startup') + script_path = os.path.join(package_path, 'jsk_pr2_sensors/hokuyo_reset_scripts') + retcode = subprocess.call('{}/upgrade /etc/ros/sensors/{}_hokuyo {}/reset.cmd'.format(script_path, self.hokuyo_name, script_path), shell=True) + self.say_something("Reset {} hokuyo".format(self.hokuyo_name)) + time.sleep(10) + + # 3 Restarting hokuyo node + os.environ['ROS_ENV_LOADER'] = '/home/applications/ros/noetic/devel/env.sh' + self.launch_process = subprocess.Popen(['roslaunch', 'jsk_pr2_startup', '{}_hokuyo.launch'.format(self.hokuyo_name)], env=os.environ) + rospy.loginfo("Restart {} hokuyo node".format(self.hokuyo_name)) + time.sleep(30) + rospy.loginfo("Restarting {} hokuyo node is Done".format(self.hokuyo_name)) + + except Exception as e: + rospy.logerr('[%s] Unable to kill %s hokuyo node, caught exception:\n%s', self.__class__.__name__, self.hokuyo_name, traceback.format_exc()) + + def run(self): + rate = rospy.Rate(1) # Router plate: 1 Hz + while not rospy.is_shutdown(): + self.check_timeout() + rate.sleep() + +if __name__ == '__main__': + try: + topic_checker = HokuyoScanChecker() + topic_checker.run() + except rospy.ROSInterruptException: + pass diff --git a/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/reset.cmd b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/reset.cmd new file mode 100644 index 0000000000..b84f61c508 --- /dev/null +++ b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/reset.cmd @@ -0,0 +1,5 @@ +*** 1 O 4 +$WP +*** 2 O 5 +$WCE +*** 3 E 0 diff --git a/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/upgrade b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/upgrade new file mode 100755 index 0000000000..edaff4dbdf Binary files /dev/null and b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/hokuyo_reset_scripts/upgrade differ diff --git a/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/tilt_hokuyo.launch b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/tilt_hokuyo.launch new file mode 100644 index 0000000000..49fc13fe05 --- /dev/null +++ b/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_sensors/tilt_hokuyo.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jsk_pr2_robot/jsk_pr2_startup/pr2_bringup.launch b/jsk_pr2_robot/jsk_pr2_startup/pr2_bringup.launch index 823f824d0e..f4d0a9cf08 100644 --- a/jsk_pr2_robot/jsk_pr2_startup/pr2_bringup.launch +++ b/jsk_pr2_robot/jsk_pr2_startup/pr2_bringup.launch @@ -77,24 +77,14 @@ - - - - - - - + + + - - - - - - - - +