def processPkgPath(paths): """ Utility function to process the attribute ROOT_PKG_DIR from settings. @param paths: List of attribute ROOT_PKG_DIR from settings.py @type paths: [(str, str/None)] @return: Processed list; each element of ROOT_PKG_DIR will be transformed into a tuple of source path and destination path which can than be used to extend the fstab file for the container creation. @rtype: [(str, str)] @raise: ValueError """ pkgDir = [] usedNames = set() for path, name in paths: checkPath(path, 'ROS Package') if not name: name = os.path.basename(path) if not isLegalName(name): raise ValueError("'{0}' is not a legal name.".format(name)) if name in usedNames: raise ValueError("Package name '{0}' is not " 'unique.'.format(name)) usedNames.add(name) # TODO: Contains container specific configuration: 'opt/rce/packages' pkgDir.append((path, os.path.join('opt/rce/packages', name))) return pkgDir
def addInterface(self, iTag, iType, clsName, addr): """ Add an interface to the ROS environment inside the container. @param iTag: Tag which is used to identify the interface in subsequent requests. @type iTag: str @param iType: Type of the interface. The type has to be of the form: {prefix}Interface whit valid prefixes: ServiceClient, ServiceProvider, Publisher, Subscriber @type iType: str @param clsName: Message type/Service type consisting of the package and the name of the message/service, i.e. 'std_msgs/Int32'. @type clsName: str @param addr: ROS name/address which the interface should use. @type addr: str """ if not isLegalName(iTag): raise InvalidRequest('Interface tag is not a valid.') if iTag in self._interfaces: raise InvalidRequest("Can not use the same interface tag '{0}' " 'in the same container twice.'.format(iTag)) try: iType = Types.encode(iType) except TypeError: raise InvalidRequest('Interface type is invalid (Unknown prefix).') interface = self._obj.createInterface(iType, clsName, addr) interface = Interface(interface, iType, clsName) self._interfaces[iTag] = interface interface.notifyOnDeath(self._interfaceDied)
def addInterface(self, iTag, iType, clsName): """ Add an interface to the Robot object. @param iTag: Tag which is used to identify the interface in subsequent requests. @type iTag: str @param iType: Type of the interface. The type consists of a prefix and a suffix. - Valid prefixes are: ServiceClient, ServiceProvider, Publisher, Subscriber - Valid suffixes are: Converter, Forwarder @type iType: str @param clsName: Message type/Service type consisting of the package and the name of the message/service, i.e. 'std_msgs/Int32'. @type clsName: str """ if not isLegalName(iTag): raise InvalidRequest('Interface tag is not a valid.') if iTag in self._interfaces: raise InvalidRequest("Can not use the same interface tag '{0}' " 'in the same robot twice.'.format(iTag)) modifier = 4 if iType.endswith('Forwarder') else 0 try: iType = Types.encode(iType) except TypeError: raise InvalidRequest('Interface type is invalid (Unknown prefix).') interface = self._obj.createInterface(iType+modifier, clsName, iTag) interface = Interface(interface, iType, clsName) self._interfaces[iTag] = interface interface.notifyOnDeath(self._interfaceDied)
def remote_createContainer(self, tag): """ Create a new Container object. @param tag: Tag which is used to identify the container in subsequent requests. @type tag: str """ if not isLegalName(tag): raise InvalidRequest('Container tag is not a valid.') if tag in self._containers or tag in self._robots: raise InvalidRequest('Tag is already used for a container ' 'or robot.') namespace, remote_container = self._realm.createContainer() container = Container(namespace, remote_container) self._containers[tag] = container container.notifyOnDeath(self._containerDied) m = 'Container {0} successfully created.'.format(tag) d = DeferredList([namespace(), remote_container()], fireOnOneErrback=True, consumeErrors=True) return d.addCallback(lambda _: m)
def addNode(self, nTag, pkg, exe, args, name, namespace): """ Add a node to the ROS environment inside the container. @param nTag: Tag which is used to identify the node in subsequent requests. @type nTag: str @param pkg: Name of ROS package where the node can be found. @type pkg: str @param exe: Name of executable (node) which should be launched. @type exe: str @param args: Additional arguments which should be used for the launch. @type args: str @param name: Name of the node under which the node should be launched. @type name: str @param namespace: Namespace in which the node should be started in the environment. @type namespace: str """ if not isLegalName(nTag): raise InvalidRequest('Node tag is not a valid.') if nTag in self._nodes: raise InvalidRequest("Can not use the same node tag '{0}' in the " 'same container twice.'.format(nTag)) node = self._obj.createNode(pkg, exe, args, name, namespace) self._nodes[nTag] = node node.notifyOnDeath(self._nodeDied)
def createRobot(self, robotID): """ Create a new Robot object. @param robotID: The robot ID associated with the new Robot object which should be created. @type robotID: str @return: The authentication key and address which are used for the websocket connection. @rtype: twisted::Deferred """ if not isLegalName(robotID): raise InvalidRequest('Robot ID is not a valid.') if (robotID in self._robots or robotID in self._containers): raise InvalidRequest('ID is already used for a container ' 'or robot.') uid = uuid4().hex robot = self._realm.createRobot(self, robotID, uid) robot = Robot(robot, uid) self._robots[robotID] = robot robot.notifyOnDeath(self._robotDied) return robot.getConnectInfo()