diff --git a/README.md b/README.md index 55f4c0c..41acf51 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,28 @@ pip3 install roslibpy https://pypi.python.org/pypi/service_identity ``` +## Building docker image +```bash +sudo docker build -t rosgraph_monitor:0.1 . +sudo docker run -it rosgraph_monitor:0.1 +//once inside the image +roscore +``` +In a new terminal +```bash +sudo docker ps -l +// check for NAMES +sudo docker exec -it NAME bash +//once inside the image +source /graph_ws/devel/setup.bash +rosrun rosgraph_monitor monitor +``` + + ## Running the system ``` roslaunch rosbridge_server rosbridge_websocket.launch roslaunch rosgraph_monitor demo.launch python3 src/rosgraph_monitor/nav_model.py rosservice call /load_observer "name: 'NavObserver'" -``` +``` \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..fc07740 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,16 @@ +FROM osrf/ros:melodic-desktop-bionic + +RUN apt-get update \ + && apt-get install -y git \ + python-catkin-tools + +RUN mkdir -p /graph_ws/src +WORKDIR /graph_ws/src +RUN git clone --depth=1 -b nav_observer https://github.com/ipa-hsd/rosgraph_monitor/ +RUN git clone --depth=1 -b SoSymPaper https://github.com/ipa-nhg/ros_graph_parser + +WORKDIR /graph_ws/ +RUN rosdep install --from-paths src --ignore-src -r -y +RUN . /opt/ros/melodic/local_setup.sh \ + && catkin build \ + && . devel/local_setup.sh diff --git a/docker/ros_entrypoint.sh b/docker/ros_entrypoint.sh new file mode 100644 index 0000000..5f6588a --- /dev/null +++ b/docker/ros_entrypoint.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -e + +# setup ros environment +source "graph_ws/devel/setup.bash" +exec "$@" \ No newline at end of file diff --git a/src/rosgraph_monitor/observer.py b/src/rosgraph_monitor/observer.py index fc1fda9..9b39ccf 100644 --- a/src/rosgraph_monitor/observer.py +++ b/src/rosgraph_monitor/observer.py @@ -57,11 +57,15 @@ def _stopped(self): class ServiceObserver(Observer): def __init__(self, name, service_name=None, service_type=None, loop_rate_hz=1): + super(ServiceObserver, self).__init__(name, loop_rate_hz) self.name = service_name self.type = service_type self.client = None - self.start_service() - super(ServiceObserver, self).__init__(name, loop_rate_hz) + try: + self.start_service() + except: + print("{} service not started".format(self.name)) + super.__del__() def start_service(self): try: @@ -89,10 +93,10 @@ def diagnostics_from_response(self, response): class TopicObserver(Observer): def __init__(self, name, loop_rate_hz, topics): + super(TopicObserver, self).__init__(name, loop_rate_hz) self._topics = topics self._id = "" self._num_topics = len(topics) - super(TopicObserver, self).__init__(name, loop_rate_hz) # Every derived class needs to override this def calculate_attr(self, msgs): diff --git a/src/rosgraph_monitor/parser.py b/src/rosgraph_monitor/parser.py index bb106cc..1f40e6d 100644 --- a/src/rosgraph_monitor/parser.py +++ b/src/rosgraph_monitor/parser.py @@ -34,7 +34,8 @@ def __init__(self, model, isFile=True): # CSB = Close Square Bracket ] OCB, CCB, ORB, CRB, SQ, OSB, CSB = map(Suppress, "{}()'[]") - name = SQ + Word(printables, excludeChars="{},'") + SQ + name = Optional(SQ) + Word(printables, + excludeChars="{},'") + Optional(SQ) real = Combine(Word(nums) + '.' + Word(nums)) @@ -99,6 +100,11 @@ def __init__(self, model, isFile=True): _from = Keyword("From").suppress() _to = Keyword("To").suppress() + # global parameters Def + _g_parameters = Keyword("Parameters").suppress() + _g_parameter = Keyword("Parameter").suppress() + _type = Keyword("type").suppress() + listStr << delimitedList(Group(OCB + delimitedList(values) + CCB)) mapStr << (OSB + delimitedList(Group(OCB + delimitedList((Group( sglQuotedString.setParseAction(removeQuotes) + Suppress(":") + values))) + CCB)) + CSB) @@ -148,6 +154,11 @@ def __init__(self, model, isFile=True): topic_connections = (_topic_connections + OCB + OneOrMore(topic_connection + Optional(",").suppress()) + CCB) + g_parameter = Group(_g_parameter + OCB + _name + name("param_name") + + _type + name("value_type") + param_value("param_value") + CCB) + g_parameters = (_g_parameters + OCB + + OneOrMore(g_parameter + Optional(",").suppress()) + CCB) + interface = Group( _interface + OCB + @@ -165,8 +176,9 @@ def __init__(self, model, isFile=True): OCB + \ _name + name("system_name") + \ _component + ORB + \ - OneOrMore(interface + Optional(",").suppress())("interfaces") + \ - CRB + Optional(topic_connections)("topic_connections") + CCB + OneOrMore(interface + Optional(",").suppress())("interfaces") + CRB \ + + Optional(topic_connections)("topic_connections") \ + + Optional(g_parameters)("global_parameters") + CCB self._model = model self._isFile = isFile @@ -177,6 +189,7 @@ def _parse_from_file(self): self._result = self.rossystem_grammar.parseFile(self._model) def parse(self): + self._result = ParseResults() try: if self._isFile: self._parse_from_file()