rtm.py
Go to the documentation of this file.
00001 ##
00002 # \file rtm.py
00003 # \brief jython library to control RT components
00004 #
00005 from org.omg.CORBA import *
00006 from org.omg.CosNaming import *
00007 from org.omg.CosNaming.NamingContextPackage import *
00008 from com.sun.corba.se.impl.encoding import EncapsOutputStream
00009 
00010 from java.lang import System, Class
00011 
00012 from RTC import *
00013 from RTM import *
00014 from OpenRTM import *
00015 from _SDOPackage import *
00016 
00017 import string, math, socket, time, sys
00018 
00019 ##
00020 # \brief root naming context
00021 #
00022 rootnc = None
00023 
00024 ##
00025 # \brief hostname where naming service is running
00026 #
00027 nshost = None
00028  
00029 ##
00030 # \brief wrapper class of RT component
00031 #
00032 class RTcomponent:
00033         ##
00034         # \brief constructor
00035         # \param self this object
00036         # \param ref IOR of RT component
00037         #
00038         def __init__(self, ref):
00039                 self.ref = ref
00040                 self.owned_ecs = ref.get_owned_contexts()
00041                 self.ec = self.owned_ecs[0]
00042                 self.ports = {}
00043                 ports = self.ref.get_ports()
00044                 for p in ports:
00045                         prof = p.get_port_profile()
00046                         name = prof.name.split('.')[1]
00047                         self.ports[name] = p
00048         
00049         ##
00050         # \brief get IOR of port
00051         # \param self this object
00052         # \param name name of the port
00053         # \return IOR of the port
00054         def port(self, name):
00055                 try:
00056                         p = self.ports[unicode(name)]
00057                 except KeyError:
00058                         p = findPort(self.ref, name)
00059                         self.ports[unicode(name)] = p
00060                 return p
00061 
00062         ##
00063         # \brief get IOR of the service
00064         # \param self this object
00065         # \param instance_name instance name of the service
00066         # \param type_name type name of hte service
00067         # \param port_name port name which provides the service
00068         # \return IOR of the service
00069         def service(self, instance_name, type_name="", port_name=""):
00070                 return findService(self, port_name, type_name, instance_name)
00071 
00072         ##
00073         # \brief update default configuration set
00074         # \param self this object
00075         # \param nvlist list of pairs of name and value
00076         def setConfiguration(self, nvlist):
00077                 setConfiguration(self.ref, nvlist)
00078 
00079         ##
00080         # \brief update value of the default configuration set
00081         # \param self this object       
00082         # \param name name of the property
00083         # \param value new value of the property
00084         def setProperty(self, name, value):
00085                 self.setConfiguration([[name, value]])
00086 
00087         ##
00088         # \brief get value of the property in the default configuration set
00089         # \param self this object       
00090         # \param name name of the property
00091         # \return value of the property or None if the property is not found
00092         def getProperty(self, name):
00093                 cfg = self.ref.get_configuration()
00094                 cfgsets = cfg.get_configuration_sets()
00095                 if len(cfgsets) == 0:
00096                         print "configuration set is not found"
00097                         return None
00098                 cfgset = cfgsets[0]
00099                 for d in cfgset.configuration_data:
00100                         if d.name == name:
00101                                 return d.value.extract_string()
00102                 return None             
00103 
00104         ##
00105         # \brief show list of property names and values
00106         # \param self this object
00107         def properties(self):
00108                 cfg = self.ref.get_configuration()
00109                 cfgsets = cfg.get_configuration_sets()
00110                 if len(cfgsets) == 0:
00111                         print "configuration set is not found"
00112                         return
00113                 cfgset = cfgsets[0]
00114                 for d in cfgset.configuration_data:
00115                         print d.name,":",d.value.extract_string()
00116                 
00117 
00118         ##
00119         # \brief activate this component
00120         # \param self this object
00121         # \param ec execution context used to activate this component
00122         def start(self, ec=None):
00123                 if ec == None:
00124                         ec = self.ec
00125                 if ec != None:
00126                         ec.activate_component(self.ref)
00127                         while self.isInactive(ec):
00128                                 time.sleep(0.01)
00129 
00130         ##
00131         # \brief deactivate this component
00132         # \param self this object
00133         # \param ec execution context used to deactivate this component
00134         def stop(self, ec=None):
00135                 if ec == None:
00136                         ec = self.ec
00137                 if ec != None:
00138                         ec.deactivate_component(self.ref)
00139                         while self.isActive(ec):
00140                                 time.sleep(0.01)
00141 
00142         ##
00143         # \brief get life cycle state of the main execution context
00144         # \param self this object
00145         # \param ec execution context from which life cycle state is obtained
00146         # \return one of LifeCycleState value or None if the main execution context is not set
00147         def getLifeCycleState(self, ec=None):
00148                 if ec == None:
00149                         ec = self.ec
00150                 if ec != None:
00151                         return ec.get_component_state(self.ref)
00152                 else:
00153                         return None
00154 
00155         ##
00156         # \brief check the main execution context is active or not
00157         # \param ec execution context
00158         # \retval 1 this component is active
00159         # \retval 0 this component is not active
00160         def isActive(self, ec=None):
00161                 return LifeCycleState.ACTIVE_STATE == self.getLifeCycleState(ec)
00162 
00163         ##
00164         # \brief check the main execution context is inactive or not
00165         # \param ec execution context
00166         # \retval 1 this component is inactive
00167         # \retval 0 this component is not inactive
00168         def isInactive(self, ec=None):
00169                 return LifeCycleState.INACTIVE_STATE == self.getLifeCycleState(ec)
00170 
00171         ##
00172         # \brief get instance name
00173         # \return instance name
00174         def name(self):
00175                 cprof = self.ref.get_component_profile()
00176                 return cprof.instance_name
00177 
00178 ##
00179 # \brief wrapper class of RTCmanager
00180 #
00181 class RTCmanager:
00182         ##
00183         # \brief constructor
00184         # \param self this object
00185         # \param ref IOR of RTCmanager
00186         #
00187         def __init__(self, ref):
00188                 self.ref = ref
00189                 osname = System.getProperty("os.name")
00190                 # assuming jython and rtcd are running on the same OS
00191                 if osname == "Mac OS X":
00192                         self.soext = ".dylib"
00193                 else: 
00194                         self.soext = ".so"
00195         
00196         ##
00197         # \brief load RT component factory
00198         # \param self this object
00199         # \param basename common part of path of the shared library and the initialize function. path is generated by basename+".so" and the initialize function is generated by basename+"Init".
00200         #
00201         def load(self, basename):
00202                 path = basename+self.soext
00203                 initfunc = basename+"Init"
00204                 try:
00205                         self.ref.load_module(path, initfunc)
00206                 except:
00207                         print "failed to load",path
00208 
00209         ##
00210         # \brief create an instance of RT component
00211         # \param self this object
00212         # \param module name of RT component factory
00213         # \param name name of RT component instance
00214         # \return an object of RTcomponent
00215         def create(self, module,name=None):
00216                 if name != None:
00217                         rtc = findRTC(name)
00218                         if rtc != None:
00219                                 print 'RTC named "',name,'" already exists.'
00220                                 return rtc
00221                 args = module
00222                 if name != None:
00223                         args += '?instance_name=' + name
00224                 ref = self.ref.create_component(args)
00225                 if ref == None:
00226                         return None
00227                 else:
00228                         return RTcomponent(ref)
00229 
00230         ##
00231         # \brief get list of factory names
00232         # \return list of factory names
00233         def get_factory_names(self):
00234                 fs = []
00235                 fps = self.ref.get_factory_profiles()
00236                 for afp in fps:
00237                         for p in afp.properties:
00238                                 if p.name == "implementation_id":
00239                                         fs.append(p.value.extract_string())
00240                 return fs
00241 
00242         ##
00243         # \brief get list of components
00244         # \return list of components
00245         def get_components(self):
00246                 cs = []
00247                 crefs = self.ref.get_components()
00248                 for cref in crefs:
00249                         c = RTcomponent(cref)
00250                         cs.append(c)
00251                 return cs       
00252 
00253         ##
00254         # \brief restart Manager
00255         def restart(self):
00256                 self.ref.shutdown()
00257                 time.sleep(1)
00258 ##
00259 # \brief unbind an object reference 
00260 # \param name name of the object
00261 # \param kind kind of the object
00262 #
00263 def unbindObject(name, kind):
00264         nc = NameComponent(name, kind)
00265         path = [nc]
00266         rootnc.unbind(path)
00267         return None
00268 
00269 ##
00270 # \brief initialize ORB 
00271 #
00272 def initCORBA():
00273         global rootnc, nshost, orb
00274         props = System.getProperties()
00275         
00276         args = string.split(System.getProperty("NS_OPT"))
00277         nshost = System.getProperty("NS_OPT").split(':')[2]
00278         if nshost == "localhost" or nshost == "127.0.0.1":
00279                 nshost = socket.gethostname()
00280         print 'nshost =',nshost
00281         orb = ORB.init(args, props)
00282 
00283         nameserver = orb.resolve_initial_references("NameService");
00284         rootnc = NamingContextHelper.narrow(nameserver);
00285         return None
00286 
00287 ##
00288 # \brief get root naming context 
00289 # \param corbaloc location of NamingService
00290 # \return root naming context
00291 #
00292 def getRootNamingContext(corbaloc):
00293         props = System.getProperties()
00294         
00295         args = ["-ORBInitRef", corbaloc]
00296         orb = ORB.init(args, props)
00297 
00298         nameserver = orb.resolve_initial_references("NameService");
00299         return NamingContextHelper.narrow(nameserver);
00300 
00301 ##
00302 # \brief get IOR of the object
00303 # \param name name of the object
00304 # \param kind kind of the object
00305 # \param rnc root naming context. If it is not specified, global variable rootnc is used
00306 # \return IOR of the object
00307 # 
00308 def findObject(name, kind="", rnc=None):
00309         nc = NameComponent(name,kind)
00310         path = [nc]
00311         if not rnc:
00312                 rnc = rootnc
00313         return rnc.resolve(path)
00314 
00315 ##
00316 # \brief get RTCmanager
00317 # \param hostname hostname where rtcd is running
00318 # \param rnc root naming context. If it is not specified, global variable rootnc is used
00319 # \return an object of RTCmanager
00320 #
00321 def findRTCmanager(hostname=None, rnc=None):
00322         if not hostname:
00323                 hostname = nshost
00324         try:
00325                 try:
00326                         cxt = findObject(hostname, "host_cxt", rnc)
00327                 except:
00328                         hostname = socket.gethostbyaddr(hostname)[0]
00329                         cxt = findObject(hostname, "host_cxt", rnc)
00330                 obj = findObject("manager","mgr",cxt)
00331                 return RTCmanager(ManagerHelper.narrow(obj))
00332         except:
00333                 print "exception in findRTCmanager("+hostname+")"
00334 
00335 ##
00336 # \brief get RT component
00337 # \param name name of the RT component
00338 # \param rnc root naming context. If it is not specified, global variable rootnc is used
00339 # \return an object of RTcomponent
00340 #
00341 def findRTC(name, rnc=None):
00342         try:
00343                 obj = findObject(name, "rtc", rnc)
00344                 rtc = RTcomponent(RTObjectHelper.narrow(obj))
00345                 cxts = rtc.ref.get_participating_contexts()
00346                 if len(cxts) > 0:
00347                         rtc.ec = cxts[0]
00348                 return rtc
00349         except:
00350                 return None
00351 
00352 ##
00353 # \brief get a port of RT component
00354 # \param rtc an object of RTcomponent
00355 # \param name name of the port
00356 # \return IOR of the port if the port is found, None otherwise
00357 #
00358 def findPort(rtc, name):
00359         ports = rtc.get_ports()
00360         cprof = rtc.get_component_profile()
00361         portname = cprof.instance_name+"."+name
00362         for p in ports:
00363                 prof = p.get_port_profile()
00364                 if prof.name == portname:
00365                         return p
00366         return None 
00367 
00368 ##
00369 # \brief set up execution context of the first RTC so that RTCs are executed sequentially
00370 # \param rtcs sequence of RTCs
00371 # \param stopEC whether stop owned ECs of slave components
00372 #
00373 def serializeComponents(rtcs, stopEC=True):
00374         if len(rtcs) < 2:
00375                 return
00376         ec = rtcs[0].ec
00377         for rtc in rtcs[1:]:
00378                 if ec != rtc.ec: 
00379                         if stopEC:
00380                                 rtc.ec.stop()
00381                         if ec.add_component(rtc.ref) == ReturnCode_t.RTC_OK:
00382                                 rtc.ec = ec
00383                         else:
00384                                 print 'error in add_component()'
00385                 else:
00386                         print 'already serialized'
00387 
00388 ##
00389 # \brief check two ports are connected or not
00390 # \retval True connected
00391 # \retval False not connected
00392 def isConnected(outP, inP):
00393         op = outP.get_port_profile()
00394         for con_prof in op.connector_profiles:
00395                 ports = con_prof.ports
00396                 if len(ports) == 2 and outP == ports[0] and inP == ports[1]:
00397                         return True
00398         return False
00399 
00400 ##
00401 # \brief disconnect ports
00402 # \param outP IOR of outPort
00403 # \param inP IOR of inPort
00404 def disconnectPorts(outP, inP):
00405         op = outP.get_port_profile()
00406         for con_prof in op.connector_profiles:
00407                 ports = con_prof.ports
00408                 if len(ports) == 2 and outP == ports[0] and inP == ports[1]:
00409                         outP.disconnect(con_prof.connector_id)
00410         return
00411 
00412 ##
00413 # \brief get data type of a port
00414 # \param port IOR of port
00415 # \return data type
00416 def dataTypeOfPort(port):
00417         prof = port.get_port_profile()
00418         prop = prof.properties
00419         for p in prop:
00420                 if p.name == "dataport.data_type":
00421                         return p.value.extract_string()
00422         return None
00423 
00424 ##
00425 # \brief connect ports
00426 # \param outP IOR of outPort 
00427 # \param inPs an IOR or a list of IORs of inPort
00428 # \param subscription subscription type. "flush", "new" or "periodic"
00429 # \param dataflow dataflow type. "Push" or "Pull"
00430 # \param bufferlength length of data buffer
00431 # \param rate rate[Hz] for subscription type "periodic"
00432 #
00433 def connectPorts(outP, inPs, subscription="flush", dataflow="Push", bufferlength=1, rate=1000):
00434         if not isinstance(inPs, list):
00435                 inPs = [inPs]
00436         for inP in inPs: 
00437                 if isConnected(outP, inP) == True:
00438                         print outP.get_port_profile().name,'and',inP.get_port_profile().name,'are already connected'
00439                         continue
00440                 if dataTypeOfPort(outP) != dataTypeOfPort(inP):
00441                         print outP.get_port_profile().name,'and',inP.get_port_profile().name,'have different data types'
00442                         continue
00443                         
00444                 con_prof = ConnectorProfile()
00445                 con_prof.connector_id = ""
00446                 con_prof.name = "connector0"
00447                 con_prof.ports = [outP, inP]
00448                 #
00449                 nv1 = NameValue()
00450                 nv1.name = "dataport.interface_type";
00451                 a1 = orb.create_any()
00452                 a1.insert_string("corba_cdr")
00453                 nv1.value = a1
00454                 #
00455                 nv2 = NameValue()
00456                 nv2.name = "dataport.dataflow_type"
00457                 a2 = orb.create_any()
00458                 a2.insert_string(dataflow)
00459                 nv2.value = a2
00460                 #
00461                 nv3 = NameValue()
00462                 nv3.name = "dataport.subscription_type"
00463                 a3 = orb.create_any()
00464                 a3.insert_string(subscription)
00465                 nv3.value = a3
00466                 #
00467                 nv4 = NameValue()
00468                 nv4.name = "dataport.buffer.length"
00469                 a4 = orb.create_any()
00470                 a4.insert_string(str(bufferlength))
00471                 nv4.value = a4
00472                 #
00473                 nv5 = NameValue()
00474                 nv5.name = "dataport.publisher.push_rate"
00475                 a5 = orb.create_any()
00476                 a5.insert_string(str(rate))
00477                 nv5.value = a5
00478                 #
00479                 con_prof.properties = [nv1, nv2, nv3, nv4, nv5]
00480                 con_prof_holder = ConnectorProfileHolder()
00481                 con_prof_holder.value = con_prof
00482                 if inP.connect(con_prof_holder) != ReturnCode_t.RTC_OK:
00483                         print "failed to connect(",outP.get_port_profile().name,'<->',inP.get_port_profile().name,")"
00484                         continue
00485                 # confirm connection
00486                 if isConnected(outP, inP) == False:
00487                         print "connet() returned RTC_OK, but not connected"
00488 
00489 ##
00490 # \brief convert data into CDR format
00491 # \param data data to be converted
00492 # \return converted data in CDR format
00493 #
00494 def data2cdr(data):
00495         holder = Class.forName(data.getClass().getCanonicalName()+"Holder",
00496                                True, data.getClass().getClassLoader())
00497         streamable = holder.newInstance()
00498         #field = holder.getField("value")
00499         #field.set(streamable, data)
00500         streamable.value = data;
00501         strm = EncapsOutputStream(orb, True)
00502         streamable._write(strm)
00503         return strm.toByteArray()
00504 
00505 ##
00506 # \brief convert data from CDR format
00507 # \param cdr in CDR format 
00508 # \param classname class name of the data
00509 # \return converted data
00510 #
00511 def cdr2data(cdr, classname):
00512         ostrm = EncapsOutputStream(orb, True)
00513         ostrm.write_octet_array(cdr, 0, len(cdr))
00514         istrm = ostrm.create_input_stream()
00515         holder = Class.forName("RTC."+classname+"Holder", True, Manager.getClassLoader())
00516         streamable = holder.newInstance()
00517         streamable._read(istrm)
00518         return streamable.value
00519 
00520 ##
00521 # \brief write data to a data port      
00522 # \param port reference of data port
00523 # \param data data to be written
00524 # \param tm after this time, a connection to write data is disconnected
00525 #
00526 def writeDataPort(port, data, tm=1.0):
00527         con_prof = ConnectorProfile()
00528         con_prof.connector_id = ""
00529         con_prof.name = "connector0"
00530         con_prof.ports = [port]
00531         #
00532         nv1 = NameValue()
00533         nv1.name = "dataport.interface_type";
00534         a1 = orb.create_any()
00535         a1.insert_string("corba_cdr")
00536         nv1.value = a1
00537         #
00538         nv2 = NameValue()
00539         nv2.name = "dataport.dataflow_type"
00540         a2 = orb.create_any()
00541         a2.insert_string("Push")
00542         nv2.value = a2
00543         #
00544         nv3 = NameValue()
00545         nv3.name = "dataport.subscription_type"
00546         a3 = orb.create_any()
00547         a3.insert_string("flush")
00548         nv3.value = a3
00549         #
00550         con_prof.properties = [nv1, nv2, nv3]
00551         con_prof_holder = ConnectorProfileHolder()
00552         con_prof_holder.value = con_prof
00553         if port.connect(con_prof_holder) != ReturnCode_t.RTC_OK:
00554                 print "failed to connect"
00555                 return None
00556         for p in con_prof_holder.value.properties:
00557                 if p.name == 'dataport.corba_cdr.inport_ior':
00558                         ior = p.value.extract_string()
00559                         obj = orb.string_to_object(ior)
00560                         inport = InPortCdrHelper.narrow(obj)
00561                         cdr = data2cdr(data)
00562                         if inport.put(cdr) != PortStatus.PORT_OK:
00563                                 print "failed to put"
00564                         time.sleep(tm)
00565                         port.disconnect(con_prof_holder.value.connector_id)
00566         return None             
00567                         
00568                 
00569 ##
00570 # \brief read data from a data port     
00571 # \param port reference of data port
00572 # \param timeout timeout[s] 
00573 # \return data 
00574 def readDataPort(port, timeout = 1.0):
00575         pprof = port.get_port_profile()
00576         for prop in pprof.properties:
00577                 if prop.name == "dataport.data_type":
00578                         classname = prop.value.extract_string()
00579                         break;
00580         con_prof = ConnectorProfile()
00581         con_prof.connector_id = ""
00582         con_prof.name = "connector0"
00583         con_prof.ports = [port]
00584         #
00585         nv1 = NameValue()
00586         nv1.name = "dataport.interface_type";
00587         a1 = orb.create_any()
00588         a1.insert_string("corba_cdr")
00589         nv1.value = a1
00590         #
00591         nv2 = NameValue()
00592         nv2.name = "dataport.dataflow_type"
00593         a2 = orb.create_any()
00594         a2.insert_string("Pull")
00595         nv2.value = a2
00596         #
00597         nv3 = NameValue()
00598         nv3.name = "dataport.subscription_type"
00599         a3 = orb.create_any()
00600         a3.insert_string("flush")
00601         nv3.value = a3
00602         #
00603         con_prof.properties = [nv1, nv2, nv3]
00604         con_prof_holder = ConnectorProfileHolder()
00605         con_prof_holder.value = con_prof
00606         if port.connect(con_prof_holder) != ReturnCode_t.RTC_OK:
00607                 print "failed to connect"
00608                 return None
00609         for p in con_prof_holder.value.properties:
00610                 #print p.name
00611                 if p.name == 'dataport.corba_cdr.outport_ior':
00612                         ior = p.value.extract_string()
00613                         obj = orb.string_to_object(ior)
00614                         outport = OutPortCdrHelper.narrow(obj)
00615                         cdr = CdrDataHolder()
00616                         tm = 0
00617                         while tm < timeout:
00618                                 try:
00619                                         outport.get(cdr)
00620                                         if len(cdr.value) > 0:
00621                                                 port.disconnect(con_prof_holder.value.connector_id)
00622                                                 return cdr2data(cdr.value, classname)
00623                                 except:
00624                                         pass
00625                                 time.sleep(0.1)
00626                                 tm = tm + 0.1
00627 
00628         port.disconnect(con_prof_holder.value.connector_id)
00629         return None             
00630                         
00631                 
00632 
00633 ##
00634 # \brief get a service of RT component
00635 # \param rtc IOR of RT component
00636 # \param port_name port name of the port which provides the service
00637 # \param type_name type name of the service
00638 # \param instance_name name of the service
00639 # \return IOR of the service
00640 #
00641 def findService(rtc, port_name, type_name, instance_name):
00642         if port_name == "":
00643                 prof = rtc.ref.get_component_profile()
00644                 #print "RTC name:",prof.instance_name
00645                 port_prof = prof.port_profiles
00646         else:
00647                 p = rtc.port(port_name)
00648                 if p == None:
00649                         print "can't find a port named",port_name
00650                         return None
00651                 else:
00652                         port_prof = [p.get_port_profile()]
00653         port = None
00654         for pp in port_prof:
00655                 #print "name:",pp.name
00656                 ifs = pp.interfaces
00657                 for aif in ifs:
00658                         #print "IF name:",aif.instance_name
00659                         #print "IF type:",aif.type_name
00660                         if aif.instance_name == instance_name and (type_name == "" or aif.type_name == type_name):
00661                                 port = pp.port_ref
00662         if port == None:
00663                 print "can't find a service named",instance_name
00664                 return None
00665         #print port
00666         con_prof = ConnectorProfile()   
00667         con_prof.name = "noname"
00668         con_prof.connector_id = ""
00669         con_prof.ports = [port]
00670         con_prof.properties = []
00671         con_prof_holder = ConnectorProfileHolder()
00672         con_prof_holder.value = con_prof
00673         port.connect(con_prof_holder)
00674         ior = con_prof_holder.value.properties[0].value.extract_string()
00675         port.disconnect(con_prof_holder.value.connector_id)
00676         return orb.string_to_object(ior)
00677 
00678 ##
00679 # \brief update default configuration set
00680 # \param rtc IOR of RT component
00681 # \param nvlist list of pairs of name and value
00682 #
00683 def setConfiguration(rtc, nvlist):
00684         cfg = rtc.get_configuration()
00685         cfgsets = cfg.get_configuration_sets()
00686         if len(cfgsets) == 0:
00687                 print "configuration set is not found"
00688                 return
00689         cfgset = cfgsets[0]
00690         for nv in nvlist:
00691                 name = nv[0]
00692                 value = nv[1]
00693                 found = False
00694                 for d in cfgset.configuration_data:
00695                         if d.name == name:
00696                                 d.value.insert_string(value)
00697                                 cfg.set_configuration_set_values(cfgset)
00698                                 found = True
00699                                 break;
00700                 if not found:
00701                         print "no such property(",name,")"
00702         cfg.activate_configuration_set('default')
00703 
00704 ##
00705 # \brief narrow ior
00706 # \param ior ior
00707 # \param klass class name 
00708 # \param package package where the class is defined
00709 def narrow(ior, klass, package="OpenHRP"):
00710         return getattr(sys.modules[package], klass+"Helper").narrow(ior)
00711 
00712 ##
00713 # \brief check if jython or python
00714 # \return True if jython
00715 def isJython():
00716         return sys.version.count("GCC") == 0
00717 
00718 initCORBA()


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Wed May 15 2019 05:02:18