roscore調(diào)用了roslaunch.main,我們繼續(xù)追蹤,進(jìn)到ros_comm-noetic-develtoolsroslaunchsrcroslaunch文件夾中,發(fā)現(xiàn)有個(gè)__init__.py文件,說(shuō)明這個(gè)文件夾是一個(gè)python包,打開__init__.py文件找到def main(argv=sys.argv),這就是roscore調(diào)用的函數(shù)roslaunch.main的實(shí)現(xiàn),如下(這里只保留主要的代碼,不太重要的刪掉了)。
def main(argv=sys.argv):
options = None
logger = None
try:
from . import rlutil
parser = _get_optparse()
(options, args) = parser.parse_args(argv[1:])
args = rlutil.resolve_launch_arguments(args)
write_pid_file(options.pid_fn, options.core, options.port)
uuid = rlutil.get_or_generate_uuid(options.run_id, options.wait_for_master)
configure_logging(uuid)
# #3088: don't check disk usage on remote machines
if not options.child_name and not options.skip_log_check:
rlutil.check_log_disk_usage()
logger = logging.getLogger('roslaunch')
logger.info("roslaunch starting with args %s"%str(argv))
logger.info("roslaunch env is %s"%os.environ)
if options.child_name:
# 這里沒執(zhí)行到,就不列出來(lái)了
else:
logger.info('starting in server mode')
# #1491 change terminal name
if not options.disable_title:
rlutil.change_terminal_name(args, options.core)
# Read roslaunch string from stdin when - is passed as launch filename.
roslaunch_strs = []
# This is a roslaunch parent, spin up parent server and launch processes.
# args are the roslaunch files to load
from . import parent as roslaunch_parent
# force a port binding spec if we are running a core
if options.core:
options.port = options.port or DEFAULT_MASTER_PORT
p = roslaunch_parent.ROSLaunchParent(uuid, args, roslaunch_strs=roslaunch_strs, is_core=options.core, port=options.port, local_only=options.local_only, verbose=options.verbose, force_screen=options.force_screen, force_log=options.force_log, num_workers=options.num_workers, timeout=options.timeout, master_logger_level=options.master_logger_level, show_summary=not options.no_summary, force_required=options.force_required, sigint_timeout=options.sigint_timeout, sigterm_timeout=options.sigterm_timeout)
p.start()
p.spin()
roslaunch.main開啟了日志,日志記錄的信息可以幫我們了解main函數(shù)執(zhí)行的順序。
我們?nèi)buntu的.ros/log/路徑下,打開roslaunch-ubuntu-52246.log日志文件,內(nèi)容如下。
通過(guò)閱讀日志我們發(fā)現(xiàn),main函數(shù)首先檢查日志文件夾磁盤占用情況,如果有剩余空間就繼續(xù)往下運(yùn)行。
然后把運(yùn)行roscore的終端的標(biāo)題給改了。
再調(diào)用ROSLaunchParent類中的函數(shù),這大概就是main函數(shù)中最重要的地方了。
ROSLaunchParent類的定義是在同一路徑下的parent.py文件中。為什么叫LaunchParent筆者也不清楚。
先不管它,我們?cè)倏慈罩荆l(fā)現(xiàn)運(yùn)行到了下面這個(gè)函數(shù),它打算啟動(dòng)XMLRPC服務(wù)器端。
所以調(diào)用的順序是:roslaunch_ init _.py文件中的main()函數(shù)調(diào)用parent.pystart()函數(shù),start()函數(shù)調(diào)用自己類中的_start_infrastructure()函數(shù),_start_infrastructure()函數(shù)調(diào)用自己類中的_start_server()函數(shù),_start_server()函數(shù)再調(diào)用server.py中的start函數(shù)。
def _start_server(self):
self.logger.info("starting parent XML-RPC server")
self.server = roslaunch.server.ROSLaunchParentNode(self.config, self.pm)
self.server.start()
我們?cè)龠M(jìn)到server.py文件中,找到ROSLaunchNode類,里面的start函數(shù)又調(diào)用了父類XmlRpcNode中的start函數(shù)。
class ROSLaunchNode(xmlrpc.XmlRpcNode):
"""
Base XML-RPC server for roslaunch parent/child processes
"""
def start(self):
logger.info("starting roslaunch XML-RPC server")
super(ROSLaunchNode, self).start()
我們來(lái)到ros_comm-noetic-develtoolsrosgraphsrcrosgraph路徑,找到xmlrpc.py文件。找到class XmlRpcNode(object)類,再進(jìn)入start(self)函數(shù),發(fā)現(xiàn)它調(diào)用了自己類的run函數(shù),run函數(shù)又調(diào)用了自己類中的_run函數(shù),_run函數(shù)又調(diào)用了自己類中的_run_init()函數(shù),在這里才調(diào)用了真正起作用的ThreadingXMLRPCServer類。
因?yàn)閙aster節(jié)點(diǎn)是用python實(shí)現(xiàn)的,所以,需要有python版的XMLRPC庫(kù)。
幸運(yùn)的是,python有現(xiàn)成的XMLRPC庫(kù),叫SimpleXMLRPCServer。SimpleXMLRPCServer已經(jīng)內(nèi)置到python中了,無(wú)需安裝。
所以,ThreadingXMLRPCServer類直接繼承了SimpleXMLRPCServer,如下。
class ThreadingXMLRPCServer(socketserver.ThreadingMixIn, SimpleXMLRPCServer)
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4344瀏覽量
62847 -
MASTER
+關(guān)注
關(guān)注
0文章
104瀏覽量
11306 -
ROS
+關(guān)注
關(guān)注
1文章
279瀏覽量
17045
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論