Skip to content

Commit

Permalink
Add resolution of option types to the documentation script. (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
wohe committed Jan 10, 2017
1 parent 1c433e6 commit 1f27268
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 52 deletions.
44 changes: 22 additions & 22 deletions docs/source/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ cartographer.mapping.proto.MapBuilderOptions
bool use_trajectory_builder_2d
Not yet documented.

mapping_2d.proto.LocalTrajectoryBuilderOptions trajectory_builder_2d_options
cartographer.mapping_2d.proto.LocalTrajectoryBuilderOptions trajectory_builder_2d_options
Not yet documented.

bool use_trajectory_builder_3d
Not yet documented.

mapping_3d.proto.LocalTrajectoryBuilderOptions trajectory_builder_3d_options
cartographer.mapping_3d.proto.LocalTrajectoryBuilderOptions trajectory_builder_3d_options
Not yet documented.

int32 num_background_threads
Number of threads to use for background computations.

SparsePoseGraphOptions sparse_pose_graph_options
cartographer.mapping.proto.SparsePoseGraphOptions sparse_pose_graph_options
Not yet documented.


Expand All @@ -85,10 +85,10 @@ int32 optimize_every_n_scans
Online loop closure: If positive, will run the loop closure while the map
is built.

mapping.sparse_pose_graph.proto.ConstraintBuilderOptions constraint_builder_options
cartographer.mapping.sparse_pose_graph.proto.ConstraintBuilderOptions constraint_builder_options
Options for the constraint builder.

mapping.sparse_pose_graph.proto.OptimizationProblemOptions optimization_problem_options
cartographer.mapping.sparse_pose_graph.proto.OptimizationProblemOptions optimization_problem_options
Options for the optimization problem.

int32 max_num_final_iterations
Expand All @@ -110,7 +110,7 @@ double sampling_ratio
double max_constraint_distance
Threshold for poses to be considered near a submap.

sensor.proto.AdaptiveVoxelFilterOptions adaptive_voxel_filter_options
cartographer.sensor.proto.AdaptiveVoxelFilterOptions adaptive_voxel_filter_options
Voxel filter used to compute a sparser point cloud for matching.

double min_score
Expand All @@ -126,16 +126,16 @@ double lower_covariance_eigenvalue_bound
bool log_matches
If enabled, logs information of loop-closing constraints for debugging.

mapping_2d.scan_matching.proto.FastCorrelativeScanMatcherOptions fast_correlative_scan_matcher_options
cartographer.mapping_2d.scan_matching.proto.FastCorrelativeScanMatcherOptions fast_correlative_scan_matcher_options
Options for the internally used scan matchers.

mapping_2d.scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options
cartographer.mapping_2d.scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options
Not yet documented.

mapping_3d.scan_matching.proto.FastCorrelativeScanMatcherOptions fast_correlative_scan_matcher_options_3d
cartographer.mapping_3d.scan_matching.proto.FastCorrelativeScanMatcherOptions fast_correlative_scan_matcher_options_3d
Not yet documented.

mapping_3d.scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options_3d
cartographer.mapping_3d.scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options_3d
Not yet documented.


Expand All @@ -160,7 +160,7 @@ double consecutive_scan_rotation_penalty_factor
bool log_solver_summary
If true, the Ceres solver summary will be logged for every optimization.

common.proto.CeresSolverOptions ceres_solver_options
cartographer.common.proto.CeresSolverOptions ceres_solver_options
Not yet documented.


Expand Down Expand Up @@ -207,16 +207,16 @@ bool use_online_correlative_scan_matching
Whether to solve the online scan matching first using the correlative scan
matcher to generate a good starting point for Ceres.

sensor.proto.AdaptiveVoxelFilterOptions adaptive_voxel_filter_options
cartographer.sensor.proto.AdaptiveVoxelFilterOptions adaptive_voxel_filter_options
Voxel filter used to compute a sparser point cloud for matching.

scan_matching.proto.RealTimeCorrelativeScanMatcherOptions real_time_correlative_scan_matcher_options
cartographer.mapping_2d.scan_matching.proto.RealTimeCorrelativeScanMatcherOptions real_time_correlative_scan_matcher_options
Not yet documented.

scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options
cartographer.mapping_2d.scan_matching.proto.CeresScanMatcherOptions ceres_scan_matcher_options
Not yet documented.

mapping_3d.proto.MotionFilterOptions motion_filter_options
cartographer.mapping_3d.proto.MotionFilterOptions motion_filter_options
Not yet documented.

double imu_gravity_time_constant
Expand All @@ -230,7 +230,7 @@ double imu_gravity_time_constant
int32 num_odometry_states
Maximum number of previous odometry states to keep.

mapping_2d.proto.SubmapsOptions submaps_options
cartographer.mapping_2d.proto.SubmapsOptions submaps_options
Not yet documented.

bool use_imu_data
Expand All @@ -254,7 +254,7 @@ int32 num_laser_fans
bool output_debug_images
If enabled, submap%d.png images are written for debugging.

LaserFanInserterOptions laser_fan_inserter_options
cartographer.mapping_2d.proto.LaserFanInserterOptions laser_fan_inserter_options
Not yet documented.


Expand All @@ -273,7 +273,7 @@ double rotation_weight
double covariance_scale
Scale applied to the covariance estimate from Ceres.

common.proto.CeresSolverOptions ceres_solver_options
cartographer.common.proto.CeresSolverOptions ceres_solver_options
Configure the Ceres solver. See the Ceres documentation for more
information: https://code.google.com/p/ceres-solver/

Expand Down Expand Up @@ -318,10 +318,10 @@ bool use_online_correlative_scan_matching
Whether to solve the online scan matching first using the correlative scan
matcher to generate a good starting point for Ceres.

mapping_2d.scan_matching.proto.RealTimeCorrelativeScanMatcherOptions real_time_correlative_scan_matcher_options
cartographer.mapping_2d.scan_matching.proto.RealTimeCorrelativeScanMatcherOptions real_time_correlative_scan_matcher_options
Not yet documented.

kalman_filter.proto.PoseTrackerOptions pose_tracker_options
cartographer.kalman_filter.proto.PoseTrackerOptions pose_tracker_options
Not yet documented.

double odometer_translational_variance
Expand Down Expand Up @@ -409,7 +409,7 @@ int32 num_laser_fans
number of scans inserted: First for initialization without being matched
against, then while being matched.

LaserFanInserterOptions laser_fan_inserter_options
cartographer.mapping_3d.proto.LaserFanInserterOptions laser_fan_inserter_options
Not yet documented.


Expand All @@ -428,7 +428,7 @@ double covariance_scale
bool only_optimize_yaw
Whether only to allow changes to yaw, keeping roll/pitch constant.

common.proto.CeresSolverOptions ceres_solver_options
cartographer.common.proto.CeresSolverOptions ceres_solver_options
Configure the Ceres solver. See the Ceres documentation for more
information: https://code.google.com/p/ceres-solver/

Expand Down
85 changes: 55 additions & 30 deletions scripts/update_configuration_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,19 @@
NODOC = 'Not yet documented.'


def ForEachProtoFile(root, callback):
for dirpath, dirnames, filenames in os.walk(root):
for name in filenames:
if name.endswith('.proto'):
path = os.path.join(dirpath, name)
print("Found '%s'..." % path)
assert not os.path.islink(path)
callback(io.open(path, encoding='UTF-8'))


class Message(object):
def __init__(self, name, preceding_comments):
def __init__(self, name, package, preceding_comments):
self.name = name
self.package = package
self.preceding_comments = preceding_comments
self.trailing_comments = None
self.options = []

def AddTrailingComments(self, comments):
self.trailing_comments = comments

def AddOption(self, name, comments):
self.options.append((name, comments))
def AddOption(self, option_type, name, comments):
self.options.append((option_type, name, comments))


def ParseProtoFile(proto_file):
Expand Down Expand Up @@ -107,7 +98,7 @@ def ParseProtoFile(proto_file):
# We reached the end of file.
break
print(" Found '%s'." % message_name)
message = Message(message_name, message_comments)
message = Message(message_name, package, message_comments)
message_list.append(message)

# We capture the contents of this message.
Expand Down Expand Up @@ -135,27 +126,68 @@ def ParseProtoFile(proto_file):
if not multiline.endswith(';'):
continue
assert len(multiline) < 200
option_name = multiline[8:-1].strip().rstrip('0123456789').strip()
assert option_name.endswith('=')
option_name = option_name[:-1].strip();
option = multiline[8:-1].strip().rstrip('0123456789').strip()
assert option.endswith('=')
option_type, option_name = option[:-1].strip().split();
print(" Option '%s'." % option_name)
multiline = None
message.AddOption(option_name, option_comments)
message.AddOption(option_type, option_name, option_comments)
option_comments = []

return message_list


def GenerateDocumentation(output_dict, proto_file):
for message in ParseProtoFile(proto_file):
def ParseProtoFilesRecursively(root):
"""Recursively parses all proto files into a list of Message objects."""
message_list = []
for dirpath, dirnames, filenames in os.walk(root):
for name in filenames:
if name.endswith('.proto'):
path = os.path.join(dirpath, name)
print("Found '%s'..." % path)
assert not os.path.islink(path)
message_list.extend(ParseProtoFile(io.open(path, encoding='UTF-8')))
return message_list


class ResolutionError(Exception):
"""Raised when resolving a message name fails."""


class Resolver(object):
def __init__(self, name_set):
self.name_set = set(iter(name_set))

def Resolve(self, message_name, package_name):
if message_name in ('bool', 'double', 'float', 'int32'):
return message_name
if message_name.startswith('.'):
return message_name[1:]
package = package_name.split('.')
for levels in range(len(package), -1, -1):
candidate = '.'.join(package[0:levels]) + '.' + message_name
if candidate in self.name_set:
return candidate
raise ResolutionError(
'Resolving %s in %s failed.' % (message_name, package_name))


def GenerateDocumentation(output_file, root):
"""Recursively generates documentation, sorts and writes it."""
message_list = ParseProtoFilesRecursively(root)
resolver = Resolver(message.name for message in message_list)

output_dict = {}
for message in message_list:
content = [message.name, '=' * len(message.name), '']
assert message.name not in output_dict
output_dict[message.name] = content
if message.preceding_comments:
content.extend(preceding_comments)
content.append('')
for option_name, option_comments in message.options:
content.append(option_name)
for option_type, option_name, option_comments in message.options:
content.append(
resolver.Resolve(option_type, message.package) + ' ' + option_name)
if not option_comments:
option_comments.append(NODOC)
for comment in option_comments:
Expand All @@ -165,13 +197,6 @@ def GenerateDocumentation(output_dict, proto_file):
content.extend(message.trailing_comments)
content.append('')


def GenerateDocumentationRecursively(output_file, root):
"""Recursively generates documentation, sorts and writes it."""
output_dict = {}
def callback(proto_file):
GenerateDocumentation(output_dict, proto_file)
ForEachProtoFile(root, callback)
output = ['\n'.join(doc) for key, doc in sorted(list(output_dict.items()))]
print('\n\n'.join(output), file=output_file)

Expand All @@ -181,7 +206,7 @@ def main():
assert not os.path.islink(ROOT) and os.path.isdir(ROOT)
output_file = io.open(TARGET, mode='w', encoding='UTF-8', newline='\n')
output_file.write(PREFIX)
GenerateDocumentationRecursively(output_file, ROOT)
GenerateDocumentation(output_file, ROOT)
output_file.write(SUFFIX)
output_file.close()

Expand Down

0 comments on commit 1f27268

Please sign in to comment.