Newer
Older
turtlebot3_noetic / src / turtlebot3_autorace_2020 / turtlebot3_autorace_core / nodes / all_core_mode_decider
#!/usr/bin/env python
# -*- coding: utf-8 -*-

################################################################################
# Copyright 2018 ROBOTIS CO., LTD.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################

# Author: Leon Jung, Gilbert, Ashe Kim

import rospy
import numpy as np
from enum import Enum
from std_msgs.msg import UInt8
from turtlebot3_autorace_msgs.msg import MovingParam

class CoreModeDecider():
    def __init__(self):
        # subscribes : invoking object detected
        self.sub_traffic_light = rospy.Subscriber('/detect/traffic_light', UInt8, self.cbInvokedByTrafficLight, queue_size=1)
        self.sub_traffic_sign = rospy.Subscriber('/detect/traffic_sign', UInt8, self.cbInvokedByTrafficSign, queue_size=1)
        self.sub_returned_mode = rospy.Subscriber('/core/returned_mode', UInt8, self.cbReturnedMode, queue_size=1)
        # publishes : decided mode
        self.pub_decided_mode = rospy.Publisher('/core/decided_mode', UInt8, queue_size=1)
        self.InvokedObject = Enum('InvokedObject', 'traffic_light traffic_sign')
        self.TrafficSign   = Enum('TrafficSign', 'intersection left right construction stop parking tunnel')
        self.CurrentMode   = Enum('CurrentMode', 'idle lane_following traffic_light intersection construction parking_lot level_crossing tunnel')
        self.fnInitMode()
      # Invoke if traffic light is detected
    def cbInvokedByTrafficLight(self, invoke_type_msg):
        rospy.loginfo("Invoke Traffic light detected")
        self.fnDecideMode(self.InvokedObject.traffic_light.value, invoke_type_msg)
    def cbInvokedByTrafficSign(self, traffic_sign_msg):
        rospy.loginfo("Invoke Traffic sign detected")
        self.fnDecideMode(self.InvokedObject.traffic_sign.value, traffic_sign_msg)
    def cbReturnedMode(self, mode):
        rospy.loginfo("Init Mode")
        self.fnInitMode()
    def fnInitMode(self):                               # starts only when the program is started initially or any mission is completed
        self.current_mode = self.CurrentMode.lane_following.value
        self.fnPublishMode()
    def fnDecideMode(self, invoked_object, msg_data):   # starts only when the traffic sign / traffic light is detected & current_mode is lane_following
        rospy.loginfo("mode --all_core_mode_decider-----------------------------")
        rospy.loginfo("mode current_mode=%d",self.current_mode)
        rospy.loginfo("mode invoked_object=%d",invoked_object)
        rospy.loginfo("mode msg_data=%d",msg_data.data)
        rospy.loginfo("mode-------------------------------")
        if self.current_mode == self.CurrentMode.lane_following.value:
            rospy.loginfo("mode current_mode %d",self.current_mode)
            if invoked_object == self.InvokedObject.traffic_light.value:    # Traffic Light detected
                rospy.loginfo("mode invoked object %d",invoked_object)
                if msg_data.data  == self.CurrentMode.intersection.value:
                    rospy.loginfo("mode detect traffic_light and chenge mode")
                    self.current_mode = self.CurrentMode.intersection.value
            elif invoked_object == self.InvokedObject.traffic_sign.value:   # Any Sign detected
                rospy.loginfo("mode Any Sign detected")
                if msg_data.data == self.TrafficSign.intersection.value:
                    rospy.loginfo("detect sign : intersection")
                    self.current_mode = self.CurrentMode.intersection.value
                elif msg_data.data == self.TrafficSign.left.value:
                    rospy.loginfo("detect sign : intersection left")
                    self.current_mode = self.CurrentMode.intersection.value
                elif msg_data.data == self.TrafficSign.right.value:
                    rospy.loginfo("detect sign : inteersection right")
                    self.current_mode = self.CurrentMode.intersection.value
                elif msg_data.data == self.TrafficSign.construction.value:
                    rospy.loginfo("detect sign : construction")
                    self.current_mode = self.CurrentMode.construction.value
                elif msg_data.data == self.TrafficSign.parking_lot.value:
                    rospy.loginfo("detect sign : parking_log")
                    self.current_mode = self.CurrentMode.parking_lot.value
                elif msg_data.data == self.TrafficSign.level_crossing.value:
                    rospy.loginfo("detect sign : level_crossing")
                    self.current_mode = self.CurrentMode.level_crossing.value
                elif msg_data.data == self.TrafficSign.tunnel.value:
                    rospy.loginfo("detect sign : tunnel")
                    self.current_mode = self.CurrentMode.tunnel.value
            else:
                pass
        elif self.current_mode == self.CurrentMode.traffic_light.value:
            if invoked_object == self.InvokedObject.traffic_light.value:    # Traffic Light detected
                rospy.loginfo("traffic_light to lane_following")
                self.current_mode = self.CurrentMode.lane_follwoing.value
            else:
                pass
        else:
            pass
        self.fnPublishMode()

    def fnPublishMode(self):
        decided_mode = UInt8()
        decided_mode.data = self.current_mode
        self.pub_decided_mode.publish(decided_mode)

    def main(self):
        rospy.spin()

if __name__ == '__main__':
    rospy.init_node('core_mode_decider')
    node = CoreModeDecider()
    node.main()