From f78011a43986cc1fff36708c85df4d9b6be9ad15 Mon Sep 17 00:00:00 2001 From: "Lux, Dominik" Date: Wed, 23 Jan 2019 09:46:35 +0100 Subject: [PATCH] More preparations for #3 Added argsparser and some Arguments (currently not working) --- scripts/core.py | 77 +++++++--- scripts/include/constants.py | 139 ++++++++++-------- scripts/include/contextbroker/cbPublisher.py | 9 +- scripts/include/contextbroker/cbSubscriber.py | 11 +- scripts/include/mapServer.py | 19 +-- scripts/include/rcm/topicManager.py | 8 +- scripts/include/ros/rosConfigurator.py | 4 +- scripts/include/ros/topicHandler.py | 14 +- scripts/include/server/requestHandler.py | 4 +- 9 files changed, 170 insertions(+), 115 deletions(-) diff --git a/scripts/core.py b/scripts/core.py index c160730..d3f9aed 100755 --- a/scripts/core.py +++ b/scripts/core.py @@ -26,45 +26,77 @@ # logwarn # Import required Python code. +import json +import os import sys import copy import rospy import signal +import argparse -from setup import launchSetup +current_path = os.path.dirname(os.path.abspath(__file__)) +FIROS_CONF_PATH = [current_path + "/../config"] -from include.constants import * +# Main function. +if __name__ == '__main__': + # Input Parsing + parser = argparse.ArgumentParser() + parser.add_argument('-P', action='store', dest='port', help='Set the Port of the Firos-Server') + parser.add_argument('--conf', action='store', dest='conf_Fold', help='Set the config-Folder for Firos') + parser.add_argument('--ros-port', action='store', dest='ros_port', help='Set the ROS-Port for Firos') + parser.add_argument('--ros-node-name', action='store', dest='ros_node_name', help='Set the ROS-Node-Name') + parser.add_argument('--loglevel', action='store', dest='loglevel', help='Set the LogLevel (INFO, WARNING, ERROR, CRITICAL)') -from include import confManager -from include.logger import Log -from include.mapServer import MapServer -from include.server.firosServer import FirosServer + + # Get Input + results = parser.parse_args() + -from include.ros.topicHandler import RosTopicHandler, loadMsgHandlers, createConnectionListeners -from include.rcm import topicManager -# Main function. -if __name__ == '__main__': + if results.conf_Fold is not None: + current_path = os.getcwd() + FIROS_CONF_PATH[0] = current_path + "/" + results.conf_Fold + # TODO DL This re-assignment is currently not working! + + + # Importing firos specific scripts + from setup import launchSetup + from include import constants as c + + from include import confManager + from include.logger import Log + from include.mapServer import MapServer + from include.server.firosServer import FirosServer + + from include.ros.topicHandler import RosTopicHandler, loadMsgHandlers, createConnectionListeners + from include.rcm import topicManager - Log("INFO", "Initializing ROS node: " + NODE_NAME) - rospy.init_node(NODE_NAME) + + + + if results.port is not None and type(results.port) is int: + c.MAP_SERVER_PORT = results.port + + if results.ros_port is not None and type(results.ros_port) is int: + c.ROSBRIDGE_PORT = results.ros_port + + if results.ros_node_name is not None and type(results.ros_node_name) is str: + c.ROS_NODE_NAME = results.ros_node_name + + if results.loglevel is not None and type(results.loglevel) is int: + c.LOGLEVEL = results.loglevel + + + Log("INFO", "Initializing ROS node: " + c.ROS_NODE_NAME) + rospy.init_node(c.ROS_NODE_NAME) Log("INFO", "Initialized") - port = None - args = copy.deepcopy(sys.argv) - args.pop(0) - for i in range(len(args)-1): - if args[i].upper() == "-P": - i = i + 1 - port = int(args[i]) - if port is None: - port = SERVER_PORT try: - server = FirosServer("0.0.0.0", port) + server = FirosServer("0.0.0.0", c.MAP_SERVER_PORT) except Exception as ex: sys.stderr.write('CB_COMMUNICATION_FAILED') exit(1) @@ -92,3 +124,4 @@ def signal_handler(signal, frame): Log("INFO", "\nPress Ctrl+C to Exit\n") server.start() + diff --git a/scripts/include/constants.py b/scripts/include/constants.py index b891e26..74cd7ee 100644 --- a/scripts/include/constants.py +++ b/scripts/include/constants.py @@ -19,71 +19,94 @@ import urllib2 import netifaces +from core import FIROS_CONF_PATH -def setConfiguration(): + + +def setConfiguration(path): try: - current_path = os.path.dirname(os.path.abspath(__file__)) - json_path = current_path.replace("scripts/include", "config/config.json") - data = json.load(open(json_path)) + data = json.load(open(path + "/config.json")) return data[data["environment"]] except: return {} configured = False +# All Constants with their default value! +PATH = None + +LOGLEVEL = "INFO" +INTERFACE = "public" + +MAP_SERVER_ADRESS = None +MAP_SERVER_PORT = 10100 +ROSBRIDGE_PORT = 9090 +CONTEXTBROKER_ADRESS = None +CONTEXTBROKER_PORT = None + +CB_THROTTLING = 0 +CB_SUB_LENGTH = 300 # In Seconds! +CB_SUB_REFRESH = 0.9 # After 90% of time is exceeded +CB_CONTEXT_TYPE = "ROBOT" + +ROS_NODE_NAME = "firos" +ROS_SUB_QUEUE_SIZE = 10 + + + if not configured: configured = True - configData = setConfiguration() - INTERFACE = configData["interface"] if "interface" in configData else "public" - LOGLEVEL = configData["log_level"] if "log_level" in configData else "INFO" - - -SERVER_PORT = configData["server"]["port"] -if("index" in configData["contextbroker"]): - INDEX_CONTEXTBROKER = { - "ADDRESS": configData["contextbroker"]["index"]["address"], - "PORT": configData["contextbroker"]["index"]["port"], - } - - DATA_CONTEXTBROKER = { - "ADDRESS": configData["contextbroker"]["data"]["address"], - "PORT": configData["contextbroker"]["data"]["port"], - } -else: - INDEX_CONTEXTBROKER = { - "ADDRESS": configData["contextbroker"]["address"], - "PORT": configData["contextbroker"]["port"], - } - - DATA_CONTEXTBROKER = { - "ADDRESS": configData["contextbroker"]["address"], - "PORT": configData["contextbroker"]["port"], - } - -# THROTTLING = "PT1S" -THROTTLING = configData["contextbroker"]["subscription"]["throttling"] -SUBSCRIPTION_LENGTH = configData["contextbroker"]["subscription"]["subscription_length"] -SUBSCRIPTION_REFRESH_DELAY = configData["contextbroker"]["subscription"]["subscription_refresh_delay"] - -SEPARATOR_CHAR = "%27" - -# ROS CONFIG -NODE_NAME = "firos" -DEFAULT_CONTEXT_TYPE = "ROBOT" -DEFAULT_QUEUE_SIZE = 10 - -if INTERFACE == "public": - IP = urllib2.urlopen('http://ip.42.pl/raw').read() -else: - netifaces.ifaddresses(INTERFACE) - IP = netifaces.ifaddresses(INTERFACE)[2][0]['addr'] - -if "map_server_port" in configData: - MAP_SERVER_PORT = configData["map_server_port"] -else: - MAP_SERVER_PORT = None - -if "rosbridge_port" in configData: - ROSBRIDGE_PORT = configData["rosbridge_port"] -else: - ROSBRIDGE_PORT = 9090 + PATH = FIROS_CONF_PATH[0] + print PATH + + configData = setConfiguration(PATH) + + if "interface" in configData: + INTERFACE = configData["interface"] + + if "log_level" in configData: + LOGLEVEL = configData["log_level"] + + if "server" in configData and "port" in configData["server"]: + MAP_SERVER_PORT = configData["server"]["port"] + + try: + CONTEXTBROKER_ADRESS = configData["contextbroker"]["address"] + CONTEXTBROKER_PORT = configData["contextbroker"]["port"] + except: + print "TODO DL" + + if "contextbroker" in configData and "subscription" in configData["contextbroker"]: + # Configuration for Subscription + subConfig = configData["contextbroker"]["subscription"] + if "throttling" in subConfig: + CB_THROTTLING = subConfig["throttling"] + + if "subscription_length" in subConfig: + CB_SUB_LENGTH = subConfig["subscription_length"] + + if "subscription_refresh_delay" in subConfig: + CB_SUB_REFRESH = subConfig["subscription_refresh_delay"] + + + if "node_name" in configData: + ROS_NODE_NAME = configData["node_name"] + + if "ros_subscriber_queue" in configData: + ROS_SUB_QUEUE_SIZE = configData["ros_subscriber_queue"] + + if "cb_type" in configData: + CB_CONTEXT_TYPE = configData["cb_type"] + + + if INTERFACE == "public": + MAP_SERVER_ADRESS = urllib2.urlopen('http://ip.42.pl/raw').read() + else: + netifaces.ifaddresses(INTERFACE) + MAP_SERVER_ADRESS = netifaces.ifaddresses(INTERFACE)[2][0]['addr'] + + if "rosbridge_port" in configData: + ROSBRIDGE_PORT = configData["rosbridge_port"] + + + diff --git a/scripts/include/contextbroker/cbPublisher.py b/scripts/include/contextbroker/cbPublisher.py index c50b49a..f9f871f 100644 --- a/scripts/include/contextbroker/cbPublisher.py +++ b/scripts/include/contextbroker/cbPublisher.py @@ -20,16 +20,15 @@ __version__ = "0.0.1a" __status__ = "Developement" -import os import json import requests from include.logger import Log -from include.constants import DATA_CONTEXTBROKER +from include.constants import CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT, PATH from include.FiwareObjectConverter.objectFiwareConverter import ObjectFiwareConverter -CB_BASE_URL = "http://{}:{}/v2/entities/".format(DATA_CONTEXTBROKER["ADDRESS"], DATA_CONTEXTBROKER["PORT"]) +CB_BASE_URL = "http://{}:{}/v2/entities/".format(CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT) CB_HEADER = {'Content-Type': 'application/json'} class CbPublisher(object): @@ -117,9 +116,7 @@ def _loadDescriptions(self, robotID): robotID: The Robot-Id-String ''' - # TODO DL no hardcoded reference to files! - current_path = os.path.dirname(os.path.abspath(__file__)) - json_path = current_path.replace("scripts/include/contextbroker", "config/robotdescriptions.json") + json_path = PATH + "/robotdescriptions.json" description_data = json.load(open(json_path)) # Check if a robotID has descriptions diff --git a/scripts/include/contextbroker/cbSubscriber.py b/scripts/include/contextbroker/cbSubscriber.py index c30f97b..06cc27e 100644 --- a/scripts/include/contextbroker/cbSubscriber.py +++ b/scripts/include/contextbroker/cbSubscriber.py @@ -26,12 +26,13 @@ import json from include.FiwareObjectConverter.objectFiwareConverter import ObjectFiwareConverter -from include.constants import DATA_CONTEXTBROKER, IP, SERVER_PORT +# from include.constants import CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT, MAP_SERVER_ADRESS, MAP_SERVER_PORT, CB_SUB_REFRESH, CB_SUB_LENGTH +from include.constants import CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT, MAP_SERVER_ADRESS, MAP_SERVER_PORT, CB_SUB_LENGTH, CB_SUB_REFRESH from include.logger import Log -CB_BASE_URL = "http://{}:{}".format(DATA_CONTEXTBROKER["ADDRESS"], DATA_CONTEXTBROKER["PORT"]) -FIROS_NOTIFY_URL = "http://{}:{}/firos".format(IP, SERVER_PORT) # TODO DL HTTP? +CB_BASE_URL = "http://{}:{}".format(CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT) +FIROS_NOTIFY_URL = "http://{}:{}/firos".format(MAP_SERVER_ADRESS, MAP_SERVER_PORT) # TODO DL HTTP? class CbSubscriber(object): ''' The CbSubscriber handles the subscriptions on the ContextBroker. @@ -99,7 +100,7 @@ def subscribeThread(self, robotID, topic): self.subscriptionIds[robotID][topic] = newSubID # Wait - time.sleep(290) # sleep TODO DL from config loaded seconds + time.sleep(int(CB_SUB_LENGTH * CB_SUB_REFRESH)) # sleep TODO DL from config loaded seconds Log("INFO", "Refreshing Subscription for " + robotID + " and topics: " + str(topic)) @@ -130,7 +131,7 @@ def subscribeJSONGenerator(self, robotID, topic): }, "attrs": [str(topic)] }, - "expires": time.strftime("%Y-%m-%dT%H:%M:%S.00Z", time.gmtime(time.time() + 300)) # TODO DL load via Configuration, ISO 8601 + "expires": time.strftime("%Y-%m-%dT%H:%M:%S.00Z", time.gmtime(time.time() + CB_SUB_LENGTH)) # TODO DL load via Configuration, ISO 8601 # "throttling": 5 # TODO DL Maybe throttle? } return json.dumps(struct) diff --git a/scripts/include/mapServer.py b/scripts/include/mapServer.py index a9e11ea..554346a 100644 --- a/scripts/include/mapServer.py +++ b/scripts/include/mapServer.py @@ -42,12 +42,13 @@ def load(): def _launchMapServer(): ## \brief If map_server is configured launches it if(MAP_SERVER_PORT): - if not os.path.exists(os.path.join(mapserver_path, 'node_modules')): - text = "---------------------------------------------------------------------------------------\n" - text += "---------------------------------------------------------------------------------------\n" - text += "FIROS is going to install mapserver's dependencies, to do this it will need root access\n" - text += "---------------------------------------------------------------------------------------\n" - text += "---------------------------------------------------------------------------------------" - print text - os.system("cd {} && sudo npm install && sudo chown -R {} node_modules".format(mapserver_path, getpass.getuser())) - subprocess.Popen(["node", mapserver_path + "mapserver.js", str(MAP_SERVER_PORT), str(ROSBRIDGE_PORT)]) + # if not os.path.exists(os.path.join(mapserver_path, 'node_modules')): + # text = "---------------------------------------------------------------------------------------\n" + # text += "---------------------------------------------------------------------------------------\n" + # text += "FIROS is going to install mapserver's dependencies, to do this it will need root access\n" + # text += "---------------------------------------------------------------------------------------\n" + # text += "---------------------------------------------------------------------------------------" + # print text + # os.system("cd {} && sudo npm install && sudo chown -R {} node_modules".format(mapserver_path, getpass.getuser())) + # subprocess.Popen(["node", mapserver_path + "mapserver.js", str(MAP_SERVER_PORT), str(ROSBRIDGE_PORT)]) + pass diff --git a/scripts/include/rcm/topicManager.py b/scripts/include/rcm/topicManager.py index 04b9c00..5f0fee2 100644 --- a/scripts/include/rcm/topicManager.py +++ b/scripts/include/rcm/topicManager.py @@ -4,7 +4,7 @@ from firos.srv import FIROS_Info from firos.msg import Robot_Event, CB_Event -from include.constants import DEFAULT_QUEUE_SIZE +from include.constants import ROS_SUB_QUEUE_SIZE, ROS_NODE_NAME from include.ros.topicHandler import robotDisconnection, loadMsgHandlers from include.rcm.rcmutils import getRobotConfig @@ -12,7 +12,7 @@ firos_connect_listener = None firos_disconnect_listener = None robot_topics_service = rospy.ServiceProxy('/firos_info', FIROS_Info) -cb_publisher = rospy.Publisher("/firos/cb_event", CB_Event, queue_size=DEFAULT_QUEUE_SIZE) +cb_publisher = rospy.Publisher("/" + ROS_NODE_NAME + "/cb_event", CB_Event, queue_size=ROS_SUB_QUEUE_SIZE) def getRobotTopics(robot_name): @@ -66,8 +66,8 @@ def setListeners(): global firos_disconnect_listener global firos_connect_listener rcm_listener = rospy.Subscriber("/rcm/robot_event", Robot_Event, onRcmEvent, {}) - firos_disconnect_listener = rospy.Subscriber("firos/disconnect", std_msgs.msg.String, onDisconnect) - firos_connect_listener = rospy.Subscriber("firos/connect", std_msgs.msg.String, onConnect) + firos_disconnect_listener = rospy.Subscriber(ROS_NODE_NAME + "/disconnect", std_msgs.msg.String, onDisconnect) + firos_connect_listener = rospy.Subscriber(ROS_NODE_NAME + "/connect", std_msgs.msg.String, onConnect) def removeListeners(): diff --git a/scripts/include/ros/rosConfigurator.py b/scripts/include/ros/rosConfigurator.py index bf693c3..1f44fef 100644 --- a/scripts/include/ros/rosConfigurator.py +++ b/scripts/include/ros/rosConfigurator.py @@ -21,7 +21,7 @@ import rostopic import rosgraph -from include.constants import NODE_NAME +from include.constants import ROS_NODE_NAME # map_regex = re.compile(ur'^.*\/(map)[\/]*$') map_regex = re.compile(ur'^.*\/(map).*$') @@ -201,7 +201,7 @@ def _isInFiros(topic_name, list2Check, nodes): if topic_name not in list2Check: return False for node in list2Check[topic_name]: - if node == "/" + NODE_NAME: + if node == "/" + ROS_NODE_NAME: using = True break diff --git a/scripts/include/ros/topicHandler.py b/scripts/include/ros/topicHandler.py index 436f12d..8aecf97 100644 --- a/scripts/include/ros/topicHandler.py +++ b/scripts/include/ros/topicHandler.py @@ -25,7 +25,7 @@ import importlib from include.logger import Log -from include.constants import DEFAULT_QUEUE_SIZE +from include.constants import ROS_SUB_QUEUE_SIZE, ROS_NODE_NAME from include.libLoader import LibLoader from include.ros.rosConfigurator import RosConfigurator from include.ros.dependencies.third_party import * @@ -128,7 +128,7 @@ def loadMsgHandlers(robot_data): if robotID not in ROS_PUBLISHER: ROS_PUBLISHER[robotID] = {} - ROS_PUBLISHER[robotID][topic] = rospy.Publisher(robotID + "/" + topic, theclass, queue_size=DEFAULT_QUEUE_SIZE) + ROS_PUBLISHER[robotID][topic] = rospy.Publisher(robotID + "/" + topic, theclass, queue_size=ROS_SUB_QUEUE_SIZE) # After initializing ROS-PUB/SUBs, intitialize ContextBroker-Subscriber based on ROS-Publishers for each robot if robotID in ROS_PUBLISHER: @@ -257,7 +257,7 @@ def rosMsg2Dict(rosClassInstance): ''' Generating a dictionary out of the instance of a ROS-Message - rosClassInstance: an actual instance of the ROS-Message (vales will be omitted) + rosClassInstance: an actual instance of the ROS-Message (values will be omitted) ''' obj = {} for key, t in zip(rosClassInstance.__slots__, rosClassInstance._slot_types): @@ -278,11 +278,11 @@ def createConnectionListeners(): ''' This creates the following listeners for firos in ROS for robot-creation and -removal and maps them to the methods below: - /firos/connect --> std_msgs/String - /firos/disconnect --> std_msgs/String + /ROS_NODE_NAME/connect --> std_msgs/String + /ROS_NODE_NAME/disconnect --> std_msgs/String ''' - subscribers.append(rospy.Subscriber("firos/disconnect", std_msgs.msg.String, robotDisconnection)) - subscribers.append(rospy.Subscriber("firos/connect", std_msgs.msg.String, _robotConnection)) + subscribers.append(rospy.Subscriber(ROS_NODE_NAME + "/disconnect", std_msgs.msg.String, robotDisconnection)) + subscribers.append(rospy.Subscriber(ROS_NODE_NAME +"/connect", std_msgs.msg.String, _robotConnection)) def robotDisconnection(data): diff --git a/scripts/include/server/requestHandler.py b/scripts/include/server/requestHandler.py index 5748368..5d77733 100644 --- a/scripts/include/server/requestHandler.py +++ b/scripts/include/server/requestHandler.py @@ -33,12 +33,12 @@ from include.ros.rosConfigurator import RosConfigurator, setWhiteList from include.ros.topicHandler import RosTopicHandler, loadMsgHandlers, ROS_PUBLISHER, ROS_SUBSCRIBER, ROS_TOPIC_AS_DICT from include.contextbroker.cbSubscriber import CbSubscriber -from include.constants import DATA_CONTEXTBROKER +from include.constants import CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT CloudSubscriber = CbSubscriber() # Only the Conversion method is used here TODO DL # Only used to query information from Context-Broker -CB_BASE_URL = "http://{}:{}/v2/entities/".format(DATA_CONTEXTBROKER["ADDRESS"], DATA_CONTEXTBROKER["PORT"]) +CB_BASE_URL = "http://{}:{}/v2/entities/".format(CONTEXTBROKER_ADRESS, CONTEXTBROKER_PORT)