Skip to content
This repository was archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
Updated to remove robotID and only use topic.
Browse files Browse the repository at this point in the history
This has something todo with #28

robots.json is now called topics.json (since we subscribe/publish on Topics!) #29
In addition to that topics.json is now redesigned. #31

Empty whitelist now does what it should #30

We now have a similar structure as described in #32
  • Loading branch information
Luxxii committed Nov 19, 2019
1 parent cdf08fe commit 0294927
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 301 deletions.
6 changes: 3 additions & 3 deletions doc/install/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class SomeExamplePublisher(Publisher):
def __init__(self):
pass

def publish(self, robotID, topic, rawMsg, msgDefinitions):
def publish(self, topic, rawMsg, msgDefinitions):
pass

def unpublish(self):
Expand Down Expand Up @@ -96,7 +96,7 @@ class SomeExampleSubscriber(Subscriber):
def __init__(self):
pass

def subscribe(self, robotID, topicList, msgDefinitions):
def subscribe(self, topicList, msgDefinitions):
pass

def unsubscribe(self):
Expand All @@ -117,7 +117,7 @@ The received Messages need to be converted into a special class which can be dir
After the received Message is converted correctly, you can publish it via:

```python
RosTopicHandler.publish(robotID, topic, convertedData, dataStruct):
RosTopicHandler.publish(topic, convertedData, dataStruct):
```

and it should be published in the ROS-World automatically!
Expand Down
48 changes: 26 additions & 22 deletions firos/include/confManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,43 +35,47 @@ def getRobots(refresh=False):
'''
try:
# Retrieves the whitelist.json. If it does not exists, it returns all topics.
robots = copy.deepcopy(RosConfigurator.systemTopics(refresh))
topics_regex = copy.deepcopy(RosConfigurator.systemTopics(refresh)) # TODO DL change to topics

# Retrieves the robots.json.
robots_json = getRobotsByJson()
if len(robots_json) == 0:
Log("ERROR", "The file 'robots.json' is either empty or does not exist!\n\nExiting")
topics_json = getTopicsByJson()
if len(topics_json) == 0:
Log("ERROR", "The file 'topics.json' is either empty or does not exist!\n\nExiting")
sys.exit(1)

# Merge robots.json into whitelist.json (overwrite if neccessary)
for robot_name in robots_json:
robot_name = str(robot_name)
if robot_name not in robots:
robots[robot_name] = {
"topics": {}
}
for topic_name in robots_json[robot_name]["topics"]:
topic = robots_json[robot_name]["topics"][topic_name]
# check if structure is as needed
for key in topics_json.keys():
if len(topics_json[key]) != 2:
Log("ERROR", "The topic: '{}', does not have a list of length 2 (topics.json)! \n\nExiting".format(key))
sys.exit(1)

# Overwrite or add!
robots[robot_name]["topics"][str(topic_name)] = {
"msg": str(topic["msg"]),
"type": str(topic["type"])
}
if not key.startswith("/"):
Log("ERROR", "The topic: '{}', does not start with '/' (topics.json)! \n\nExiting".format(key))
sys.exit(1)

return robots
if topics_json[key][1] not in ["publisher", "subscriber"]:
Log("ERROR", "The topic: '{}', does not specify publisher or subscriber (topics.json)! \n\nExiting".format(key))
sys.exit(1)


# Merge both dictionaties:
# Here topics_json overrides entries in topics_regex:
topics_regex.update(topics_json)
topics = topics_regex

return topics

except Exception as e:
traceback.print_exc()
Log("ERROR", e)
return {}


def getRobotsByJson():
''' Load the 'robots.json'-File
def getTopicsByJson():
''' Load the 'topics.json'-File
'''
try:
json_path = C.PATH + "/robots.json"
json_path = C.PATH + "/topics.json"
return json.load(open(json_path))
except:
return {}
24 changes: 9 additions & 15 deletions firos/include/libLoader.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class LibLoader:
the class could not be generated), this LibLoader tries to load the message via
roslib. If every method fails FIROS will shutdown, since FIROS need the messages
due to rospy beforehand. At least for The Subscriptions and Publishes defined in
'robots.json'
'topics.json'
'''

# Our custom search path for genpy
Expand Down Expand Up @@ -114,20 +114,14 @@ def _init_searchpath_for_available_msgs_on_system():


@staticmethod
def loadFromSystem(msgType, robotID, topic):
def loadFromSystem(msgType, topic):
''' This actually tries all three methods mentioned above.
Remark: If the regex does not find a match, we are also not able
to parse the Configuration-File ('robots.json') and exit.
'''
matches = re.search(regex, msgType) # get (PACKAGE).(msg).(MSGTYPE)
splits = msgType.split("/")

if matches is not None:
# We have a Match, we can start to get the Message now!
module_name = str(matches.group(1)) + str(matches.group(2))[:-4] # PACKAGE + '.msg'
modules = str(matches.group(3)).split(".") # MSGTYPE
modules = modules[1: len(modules)]
module_msg = modules[0]
if len(splits) == 2:
module_name = splits[0] # PACKAGE
module_msg = splits[1] # MESSAGE


##### 1: Try to load it via Python-Import
Expand Down Expand Up @@ -167,7 +161,7 @@ def loadFromSystem(msgType, robotID, topic):
LibLoader.isGenerated = True
module = imp.load_source(module_msg, msgsFold + module_name + "/_" + module_msg + ".py")
clazz = getattr(module, module_msg)
Log("INFO", "Message {}/{}.msg succesfully loaded.".format(module_name, module_msg))
Log("INFO", "Message {}/{} succesfully loaded.".format(module_name, module_msg))
return clazz


Expand All @@ -176,10 +170,10 @@ def loadFromSystem(msgType, robotID, topic):
try:
import roslib.message
import rostopic
type_name = rostopic.get_topic_type('/{}/{}'.format(robotID, topic), blocking=False)[0]
type_name = rostopic.get_topic_type(topic, blocking=False)[0]
if type_name:
clazz = roslib.message.get_message_class(type_name)
Log("INFO", "Message {}/{}.msg loaded via roslib.message!".format(module_name, module_msg))
Log("INFO", "Message {}/{} loaded via roslib.message!".format(module_name, module_msg))
return clazz
except Exception:
pass
Expand Down
26 changes: 12 additions & 14 deletions firos/include/pubsub/contextbroker/cbPublisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,11 @@ def __init__(self):
self.CB_BASE_URL = "http://{}:{}/v2/entities/".format(data["address"], data["port"])


def publish(self, robotID, topic, rawMsg, msgDefintionDict):
def publish(self, topic, rawMsg, msgDefintionDict):
''' This is the actual publish-Routine which updates and creates Entities on the
ContextBroker. It also keeps track via posted_history on already posted entities and topics
robotID: A string corresponding to the Robot-Id
topic: Also a string, corresponding to the topic of the robot
topic: a string, corresponding to the topic in ros
rawMsg: the raw data directly obtained from rospy
msgDefintionDict: The Definition as obtained directly from ROS-Messages
Expand All @@ -93,25 +92,24 @@ def publish(self, robotID, topic, rawMsg, msgDefintionDict):


# if struct not initilized, intitilize it even on ContextBroker!
if robotID + "/" + topic not in self.posted_history:
self.posted_history[robotID + "/" + topic] = rawMsg
if topic not in self.posted_history:
self.posted_history[topic] = rawMsg

obj = {s: getattr(rawMsg, s, None) for s in rawMsg.__slots__}
obj["type"] = rawMsg._type.replace("/", ".") # OCB Specific!!
obj["id"] = (robotID + "/" + topic).replace("/", ".") # OCB Specific!!
jsonStr = ObjectFiwareConverter.obj2Fiware(obj, ind=0, dataTypeDict=msgDefintionDict, ignorePythonMetaData=True)

obj["id"] = (topic).replace("/", ".") # OCB Specific!!
jsonStr = ObjectFiwareConverter.obj2Fiware(obj, ind=0, dataTypeDict=msgDefintionDict, ignorePythonMetaData=True)
response = requests.post(self.CB_BASE_URL, data=jsonStr, headers=self.CB_HEADER)
self._responseCheck(response, attrAction=0, topEnt=robotID)
self._responseCheck(response, attrAction=0, topEnt=topic)
return

# Replace previous rawMsg with current one
self.posted_history[robotID + "/" + topic] = rawMsg
self.posted_history[topic] = rawMsg

# Create Update-JSON
obj = {s: getattr(rawMsg, s, None) for s in rawMsg.__slots__}
obj["type"] = rawMsg._type.replace("/", ".") # OCB Specific!!
obj["id"] = (robotID + "/" + topic).replace("/", ".") # OCB Specific!!
obj["id"] = (topic).replace("/", ".") # OCB Specific!!
jsonStr = ObjectFiwareConverter.obj2Fiware(obj, ind=0, dataTypeDict=msgDefintionDict, ignorePythonMetaData=True, showIdValue=False)

# Update attribute on ContextBroker
Expand All @@ -121,7 +119,7 @@ def publish(self, robotID, topic, rawMsg, msgDefintionDict):

def unpublish(self):
'''
Removes all previously tracked Entities/Robots on ContextBroker
Removes all previously tracked topics on ContextBroker
This method also gets automaticall called, someone sent Firos the Shutdown Signal
'''
for idd in self.posted_history.keys():
Expand All @@ -140,11 +138,11 @@ def _responseCheck(self, response, attrAction=0, topEnt=None):
'''
if not response.ok:
if attrAction == 0:
Log("WARNING", "Could not create Entitiy/Robot {} in Contextbroker :".format(topEnt))
Log("WARNING", "Could not create Entitiy {} in Contextbroker :".format(topEnt))
Log("WARNING", response.content)
elif attrAction == 1:
Log("ERROR", "Cannot update attributes in Contextbroker for topic: {} :".format(topEnt))
Log("ERROR", response.content)
else:
Log("WARNING", "Could not delete Entitiy/Robot {} in Contextbroker :".format(topEnt))
Log("WARNING", "Could not delete Entitiy {} in Contextbroker :".format(topEnt))
Log("WARNING", response.content)
Loading

0 comments on commit 0294927

Please sign in to comment.