2019-10-04 01:08:53 +08:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
# Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de
|
|
|
|
|
# Barcelona (UAB).
|
|
|
|
|
#
|
|
|
|
|
# This work is licensed under the terms of the MIT license.
|
|
|
|
|
# For a copy, see <https://opensource.org/licenses/MIT>.
|
|
|
|
|
|
|
|
|
|
import glob
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
try:
|
2019-11-19 20:12:36 +08:00
|
|
|
|
carla_lib_name = 'carla-*%d.%d-%s.egg' % (
|
2019-10-04 01:08:53 +08:00
|
|
|
|
sys.version_info.major,
|
|
|
|
|
sys.version_info.minor,
|
2019-11-19 20:12:36 +08:00
|
|
|
|
'win-amd64' if os.name == 'nt' else 'linux-x86_64')
|
|
|
|
|
sys.path.append(glob.glob('../carla/dist/%s' % carla_lib_name)[0])
|
2019-10-04 01:08:53 +08:00
|
|
|
|
except IndexError:
|
2019-11-19 20:12:36 +08:00
|
|
|
|
print('\n [ERROR] Could not find "%s"' % carla_lib_name)
|
|
|
|
|
print(' Blueprint library docs will not be generated')
|
|
|
|
|
print(" .---------------------------------------------------.")
|
|
|
|
|
print(" | Make sure the python client is compiled! |")
|
|
|
|
|
print(" '---------------------------------------------------'\n")
|
|
|
|
|
# We don't provide an error to prvent Travis checks failing
|
|
|
|
|
sys.exit(0)
|
2019-10-04 01:08:53 +08:00
|
|
|
|
|
|
|
|
|
import carla
|
|
|
|
|
|
|
|
|
|
COLOR_LIST = '#498efc'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def join(elem, separator=''):
|
|
|
|
|
return separator.join(elem)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def color(col, buf):
|
|
|
|
|
return join(['<font color="', col, '">', buf, '</font>'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def valid_dic_val(dic, value):
|
|
|
|
|
return value in dic and dic[value]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def italic(buf):
|
|
|
|
|
return join(['_', buf, '_'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def bold(buf):
|
|
|
|
|
return join(['**', buf, '**'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parentheses(buf):
|
|
|
|
|
return join(['(', buf, ')'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sub(buf):
|
|
|
|
|
return join(['<sub>', buf, '</sub>'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def code(buf):
|
|
|
|
|
return join(['`', buf, '`'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MarkdownFile:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._data = ""
|
|
|
|
|
self._list_depth = 0
|
|
|
|
|
self.endl = ' \n'
|
|
|
|
|
|
|
|
|
|
def data(self):
|
|
|
|
|
return self._data
|
|
|
|
|
|
|
|
|
|
def list_push(self, buf=''):
|
|
|
|
|
if buf:
|
|
|
|
|
self.text(join([
|
|
|
|
|
' ' * self._list_depth if self._list_depth != 0 else '', '- ', buf]))
|
|
|
|
|
self._list_depth = (self._list_depth + 1)
|
|
|
|
|
|
|
|
|
|
def list_pushn(self, buf):
|
|
|
|
|
self.list_push(join([buf, self.endl]))
|
|
|
|
|
|
|
|
|
|
def list_pop(self):
|
|
|
|
|
self._list_depth = max(self._list_depth - 1, 0)
|
|
|
|
|
|
|
|
|
|
def list_popn(self):
|
|
|
|
|
self.list_pop()
|
|
|
|
|
self._data = join([self._data, '\n'])
|
|
|
|
|
|
|
|
|
|
def list_depth(self):
|
|
|
|
|
if self._data.strip()[-1:] != '\n' or self._list_depth == 0:
|
|
|
|
|
return ''
|
|
|
|
|
return join([' ' * self._list_depth])
|
|
|
|
|
|
|
|
|
|
def text(self, buf):
|
|
|
|
|
self._data = join([self._data, buf])
|
|
|
|
|
|
|
|
|
|
def textn(self, buf):
|
|
|
|
|
self._data = join([self._data, self.list_depth(), buf, self.endl])
|
|
|
|
|
|
|
|
|
|
def not_title(self, buf):
|
|
|
|
|
self._data = join([
|
|
|
|
|
self._data, '\n', self.list_depth(), '<h1>', buf, '</h1>', '\n'])
|
|
|
|
|
|
|
|
|
|
def title(self, strongness, buf):
|
|
|
|
|
self._data = join([
|
|
|
|
|
self._data, '\n', self.list_depth(), '#' * strongness, ' ', buf, '\n'])
|
|
|
|
|
|
|
|
|
|
def new_line(self):
|
|
|
|
|
self._data = join([self._data, self.endl])
|
|
|
|
|
|
|
|
|
|
def code_block(self, buf, language=''):
|
|
|
|
|
return join(['```', language, '\n', self.list_depth(), buf, '\n', self.list_depth(), '```\n'])
|
|
|
|
|
|
|
|
|
|
|
2019-11-15 23:47:35 +08:00
|
|
|
|
def generate_pb_docs():
|
2019-10-04 01:08:53 +08:00
|
|
|
|
"""Generates markdown file"""
|
2019-11-15 23:47:35 +08:00
|
|
|
|
|
|
|
|
|
print('Generating API blueprint documentation...')
|
2019-10-04 01:08:53 +08:00
|
|
|
|
client = carla.Client('127.0.0.1', 2000)
|
|
|
|
|
client.set_timeout(2.0)
|
|
|
|
|
world = client.get_world()
|
|
|
|
|
|
|
|
|
|
bp_dict = {}
|
|
|
|
|
blueprints = [bp for bp in world.get_blueprint_library().filter('*')] # Returns list of all blueprints
|
|
|
|
|
blueprint_ids = [bp.id for bp in world.get_blueprint_library().filter('*')] # Returns list of all blueprint ids
|
|
|
|
|
|
|
|
|
|
# Creates a dict key = walker, static, prop, vehicle, sensor, controller; value = [bp_id, blueprint]
|
|
|
|
|
for bp_id in sorted(blueprint_ids):
|
|
|
|
|
bp_type = bp_id.split('.')[0]
|
|
|
|
|
value = []
|
|
|
|
|
for bp in blueprints:
|
|
|
|
|
if bp.id == bp_id:
|
|
|
|
|
value = [bp_id, bp]
|
|
|
|
|
if bp_type in bp_dict:
|
|
|
|
|
bp_dict[bp_type].append(value)
|
|
|
|
|
else:
|
|
|
|
|
bp_dict[bp_type] = [value]
|
|
|
|
|
|
|
|
|
|
# Actual documentation
|
|
|
|
|
md = MarkdownFile()
|
|
|
|
|
md.not_title('Blueprint Library')
|
|
|
|
|
md.textn(
|
|
|
|
|
"The Blueprint Library ([`carla.BlueprintLibrary`](../python_api/#carlablueprintlibrary-class)) " +
|
|
|
|
|
"is a summary of all [`carla.ActorBlueprint`](../python_api/#carla.ActorBlueprint) " +
|
|
|
|
|
"and its attributes ([`carla.ActorAttribute`](../python_api/#carla.ActorAttribute)) " +
|
|
|
|
|
"available to the user in CARLA.")
|
|
|
|
|
|
|
|
|
|
md.textn("\nHere is an example code for printing all actor blueprints and their attributes:")
|
|
|
|
|
md.textn(md.code_block("blueprints = [bp for bp in world.get_blueprint_library().filter('*')]\n"
|
2019-11-15 23:47:35 +08:00
|
|
|
|
"for blueprint in blueprints:\n"
|
|
|
|
|
" print(blueprint.id)\n"
|
|
|
|
|
" for attr in blueprint:\n"
|
|
|
|
|
" print(' - {}'.format(attr))", "py"))
|
2019-10-04 01:08:53 +08:00
|
|
|
|
md.textn("Check out our [blueprint tutorial](../python_api_tutorial/#blueprints).")
|
|
|
|
|
|
|
|
|
|
for key, value in bp_dict.items(): # bp types, bp's
|
|
|
|
|
md.title(3, key) # Key = walker, static, controller, sensor, vehicle
|
|
|
|
|
for bp in sorted(value): # Value = bp[0]= name bp[1]= blueprint
|
|
|
|
|
md.list_pushn(bold(color(COLOR_LIST, bp[0]))) # bp name
|
|
|
|
|
md.list_push(bold('Attributes:') + '\n')
|
|
|
|
|
for attr in sorted(bp[1], key=lambda x: x.id): # for attribute in blueprint
|
|
|
|
|
md.list_push(code(attr.id))
|
|
|
|
|
md.text(' ' + parentheses(italic(str(attr.type))))
|
|
|
|
|
if attr.is_modifiable:
|
|
|
|
|
md.text(sub(italic(' – Modifiable')))
|
|
|
|
|
md.list_popn()
|
|
|
|
|
md.list_pop()
|
|
|
|
|
md.list_pop()
|
|
|
|
|
md.list_pop()
|
|
|
|
|
return md.data()
|
|
|
|
|
|
|
|
|
|
|
2019-11-15 23:47:35 +08:00
|
|
|
|
def main():
|
|
|
|
|
|
|
|
|
|
script_path = os.path.dirname(os.path.abspath(__file__))
|
2019-10-04 01:08:53 +08:00
|
|
|
|
|
|
|
|
|
try:
|
2019-11-15 23:47:35 +08:00
|
|
|
|
docs = generate_pb_docs()
|
2019-10-04 01:08:53 +08:00
|
|
|
|
|
2019-11-15 23:47:35 +08:00
|
|
|
|
except RuntimeError:
|
|
|
|
|
print("\n [ERROR] Can't establish connection with the simulator")
|
|
|
|
|
print(" .---------------------------------------------------.")
|
|
|
|
|
print(" | Make sure the simulator is connected! |")
|
|
|
|
|
print(" '---------------------------------------------------'\n")
|
2019-11-19 20:12:36 +08:00
|
|
|
|
# We don't provide an error to prvent Travis checks failing
|
2019-11-18 21:11:26 +08:00
|
|
|
|
sys.exit(0)
|
2019-10-04 01:08:53 +08:00
|
|
|
|
|
2019-11-15 23:47:35 +08:00
|
|
|
|
with open(os.path.join(script_path, '../../Docs/bp_library.md'), 'w') as md_file:
|
|
|
|
|
md_file.write(docs)
|
|
|
|
|
print("Done!")
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|