fix docs autogeneration

This commit is contained in:
Samuel Sadok
2021-06-02 17:18:26 +02:00
parent c5720564d7
commit 48433c61c6
3 changed files with 72 additions and 49 deletions

View File

@@ -45,8 +45,8 @@ interfaces:
a very large PSU or are running of a battery you may encounter
this error when executing high speed movements with a high current
limit. To limit your PSU power draw you can limit your motor
current and/or velocity limit `controller.config.vel_limit` and
`motor.config.current_lim`.
current and/or velocity limit `Axis:controller.config.vel_limit` and
`Axis:motor.config.current_lim`.
DC_BUS_OVER_VOLTAGE:
brief: The DC voltage exceeded the limit configured in `config.dc_bus_overvoltage_trip_level`.
doc: |
@@ -67,12 +67,12 @@ interfaces:
resistor value.
DC_BUS_OVER_REGEN_CURRENT:
doc: |
Current flowing back into the power supply exceeded `odrv.config.dc_max_negative_current`.
Current flowing back into the power supply exceeded `config.dc_max_negative_current`.
This can happen if your brake resistor is unable to handle the braking current. Check that
`(V_power_supply / Brake_resistance) > (total motor.config.current_lim + total motor.config.current_lim_margin)`.
DC_BUS_OVER_CURRENT:
doc: |
Too much current was pulled from the power supply. `odrv.ibus` exceeded `odrv.config.dc_max_positive_current`.
Too much current was pulled from the power supply. `ibus` exceeded `config.dc_max_positive_current`.
BRAKE_DEADTIME_VIOLATION:
BRAKE_DUTY_CYCLE_NAN:
INVALID_BRAKE_RESISTANCE: {doc: '`config.brake_resistance` is non-positive or NaN. Make sure that `config.brake_resistance` is a positive number.'}
@@ -182,7 +182,7 @@ interfaces:
- A GPIO was used as an interrupt input for two internal components
or two GPIOs that are mutually exclusive in their interrupt
capability were both used as interrupt input.
Example: `step_gpio_pin` of both axes were set to the same GPIO.
Example: `Axis:config.step_gpio_pin` of both axes were set to the same GPIO.
oscilloscope: {type: Oscilloscope}
can: {type: Can}
@@ -344,8 +344,8 @@ interfaces:
The brake duty cycle is increased by the following amount:
* `vbus_voltage` == `dc_bus_overvoltage_ramp_start` => brake_duty_cycle += 0%
* `vbus_voltage` == `dc_bus_overvoltage_ramp_end` => brake_duty_cycle += 100%
* `ODrive:vbus_voltage` == `dc_bus_overvoltage_ramp_start` => brake_duty_cycle += 0%
* `ODrive:vbus_voltage` == `dc_bus_overvoltage_ramp_end` => brake_duty_cycle += 100%
Remarks:
- This feature is active even when all motors are disarmed.
@@ -354,7 +354,7 @@ interfaces:
type: float32
status: experimental
brief: See `enable_dc_bus_overvoltage_ramp`.
doc: Do not set this lower than your usual `vbus_voltage`,
doc: Do not set this lower than your usual `ODrive:vbus_voltage`,
unless you like fried brake resistors.
dc_bus_overvoltage_ramp_end:
type: float32
@@ -414,7 +414,7 @@ interfaces:
bit: 11
brief: The axis watchdog timer expired.
doc: |
An amount of time greater than `axis.config.watchdog_timeout` passed
An amount of time greater than `config.watchdog_timeout` passed
without the watchdog being fed.
MIN_ENDSTOP_PRESSED:
brief: The min endstop was pressed
@@ -662,15 +662,15 @@ interfaces:
bit: 10
doc: |
The current sense circuit saturated the current sense amplifier.
This can be caused by setting `motor.config.current_lim` higher than
`motor.config.requested_current_range`. If this happens, increase the
This can be caused by setting `config.current_lim` higher than
`config.requested_current_range`. If this happens, increase the
requested current range, save the configuration, and reboot the controller.
CURRENT_LIMIT_VIOLATION:
bit: 12
doc: |
The motor current exceeded `motor.config.current_lim + motor.config.current_lim_margin`.
The current controller is a PI controller, so it can experience overshoot. The PI gains
are automatically calculated based on `motor.config.current_control_bandwidth` and the
are automatically calculated based on `config.current_control_bandwidth` and the
motor resistance and inductance (pole placement). Some overshoot is normal, so a sensible
solution is to increase the current limit margin if your current limit is large.
MODULATION_IS_NAN: {bit: 16}
@@ -682,8 +682,8 @@ interfaces:
I_BUS_OUT_OF_RANGE:
doc: |
The DC current sourced/sunk by this motor exceeded the configured
hard limits. More specifically `i_bus` fell outside of the range
`config.i_bus_hard_min` ... `config.i_bus_hard_max`.
hard limits. More specifically `I_bus` fell outside of the range
`config.I_bus_hard_min` ... `config.I_bus_hard_max`.
BRAKE_RESISTOR_DISARMED:
doc: |
An attempt was made to run the motor PWM while the brake resistor was enabled but disarmed.
@@ -693,14 +693,14 @@ interfaces:
SYSTEM_LEVEL:
doc: |
The motor had to be disarmed because of a system level error.
See `ODrive.Error` for more details.
See `ODrive:error` for more details.
BAD_TIMING: {doc: The main control loop got out of sync with the motor control loop. This could indicate that the main control loop got stuck.}
UNKNOWN_PHASE_ESTIMATE: {doc: The current controller did not get a valid angle input. Maybe you didn't calibrate the encoder.}
UNKNOWN_PHASE_VEL: {doc: The motor controller did not get a valid phase velocity input.}
UNKNOWN_TORQUE: {doc: The motor controller did not get a valid torque input.}
UNKNOWN_CURRENT_COMMAND: {doc: The current controller did not get a valid current setpoint. Maybe you didn't configure the controller correctly.}
UNKNOWN_CURRENT_MEASUREMENT: {doc: The current controller did not get a valid current measurement.}
UNKNOWN_VBUS_VOLTAGE: {doc: The current controller did not get a valid `vbus_voltage` measurement.}
UNKNOWN_VBUS_VOLTAGE: {doc: The current controller did not get a valid `ODrive:vbus_voltage` measurement.}
UNKNOWN_VOLTAGE_COMMAND: {doc: The current controller did not get a valid feedforward voltage setpoint.}
UNKNOWN_GAINS: {doc: The current controller gains were not configured. Run motor calibration or set `config.phase_resistance` and `config.phase_inductance` manually.}
CONTROLLER_INITIALIZING: {doc: Internal value used while the controller is not yet ready to generate PWM timings.}
@@ -779,7 +779,7 @@ interfaces:
type: float32
unit: A
doc: |
If the controller fails to keep this motor's DC current (`I_bus`)
If the controller fails to keep this motor's DC current (`ODrive.Motor:I_bus`)
above this value the motor gets disarmed immediately. Most likely
you want a negative value here. Set to -inf to disable. Take noise
into account when chosing a value.
@@ -787,7 +787,7 @@ interfaces:
type: float32
unit: A
doc: |
If the controller fails to keep this motor's DC current (`I_bus`)
If the controller fails to keep this motor's DC current (`ODrive.Motor:I_bus`)
below this value the motor gets disarmed immediately. Usually this
is set in conjunction with `I_bus_hard_min`. Set to inf to disable.
Take noise into account when chosing a value.
@@ -859,7 +859,7 @@ interfaces:
the speed limit. You can set `config.enable_overspeed_error` to False
to disable this error.
INVALID_INPUT_MODE:
brief: The `controller.config.input_mode` setting was set to an invalid value. See InputMode for available values
brief: The `config.input_mode` setting was set to an invalid value. See InputMode for available values
doc: |
Input modes and control modes are separate concepts. A control mode sets the type of control to be used,
like position, velocity, or torque control. Input modes modify the input given (`input_pos`, etc) to
@@ -1027,12 +1027,12 @@ interfaces:
measure the CPR. So you should also double check this value.
If you are still having issues, you can try to increase
`encoder.config.calib_scan_distance` up to a factor of 4 above the default.
`config.calib_scan_distance` up to a factor of 4 above the default.
If your encoder cpr and motor pole pair settings are correct,
this error can be caused because motor cogging makes the motor
move less or more than commanded. You can fix this by increasing
`encoder.config.calib_scan_distance`.
`config.calib_scan_distance`.
Note that the AMT encoders are configurable using the micro-
switches on the encoder PCB and so you may need to check that
@@ -1223,7 +1223,7 @@ valuetypes:
ANALOG_IN:
doc: |
The pin can be used for one or more of these functions:
Sin/cos encoders, analog input, `get_adc_voltage`.
Sin/cos encoders, analog input, `get_adc_voltage()`.
UART_A: {doc: See `config.enable_uart_a`.}
UART_B: {doc: This mode is not supported on ODrive v3.x.}
UART_C: {doc: This mode is not supported on ODrive v3.x.}
@@ -1232,7 +1232,7 @@ valuetypes:
SPI_A: {doc: Note that the SPI pins on ODrive v3.x are hardwired so they
cannot be configured through software. Consequently, even though SPI_A
is exposed, this mode is of no use on ODrive v3.x.}
PWM: {doc: See `config.gpio0_pwm_mapping`.}
PWM: {doc: See `config.gpio1_pwm_mapping`.}
ENC0: {doc: The pin is used by quadrature encoder 0.}
ENC1: {doc: The pin is used by quadrature encoder 1.}
ENC2: {doc: This mode is not supported on ODrive v3.x.}
@@ -1299,7 +1299,7 @@ valuetypes:
brief: Run lockin spin.
doc: |
Can only be entered if the motor is calibrated (`motor.is_calibrated`)
or the motor direction is unspecified (`motor.config.direction` == 1)
or the motor direction is unspecified (`encoder.config.direction` == 1)
ENCODER_DIR_FIND:
brief: Run encoder direction search.
doc: |
@@ -1359,7 +1359,7 @@ valuetypes:
### Valid Inputs:
* `input_pos`
* `input_vel`
* `input_current`
* `input_torque`
### Valid Control modes:
* `CONTROL_MODE_VOLTAGE_CONTROL`
@@ -1404,9 +1404,9 @@ valuetypes:
![Trapezoidal Planner Response](../TrapTrajPosVel.PNG)
### Configuration Values:
* `trap_traj.config.vel_limit`
* `trap_traj.config.accel_limit`
* `trap_traj.config.decel_limit`
* `Axis:trap_traj.config.vel_limit`
* `Axis:trap_traj.config.accel_limit`
* `Axis:trap_traj.config.decel_limit`
* `config.inertia`
### Valid Inputs:
@@ -1421,7 +1421,7 @@ valuetypes:
* `config.torque_ramp_rate`
### Valid Inputs:
* `input_current`
* `input_torque`
### Valid Control Modes:
* `CONTROL_MODE_TORQUE_CONTROL`

View File

@@ -7,6 +7,14 @@ download:
text: 'download as YAML'
---
[% set attr_lookup_table =
{
'ODrive': '<odrv>',
'ODrive.Axis': '<odrv>.<axis>',
'ODrive.Motor': '<odrv>.<axis>.motor',
}
%]
[%- macro interface_ref(type) -%]
**[['[']]<span [% if type.brief %]title="[[type.brief]]"[% endif %]>[[type.name]]</span>[[']']]([[type.fullname | lower]])**
[%- endmacro %]
@@ -19,8 +27,8 @@ download:
[%- endif %]
[%- endmacro %]
[% macro attr_ref(token, attr) -%]
**[['[']]<span [% if attr.brief %]title="[[attr.brief]]"[% endif %]>[[token]]</span>[[']']]([[attr.parent.fullname | lower]]#[[attr.name]])**
[% macro attr_ref(token, scope, intf, attr) -%]
**[['[']]<span [% if attr.brief %]title="[[attr.brief]]"[% endif %]>[% if intf != scope %][[attr_lookup_table[intf.fullname] | html_escape]].[% endif %][[token]]</span>[[']']]([[attr.parent.fullname | lower]]#[[attr.name]])**
[%- endmacro %]
[% if interface %]
@@ -131,7 +139,7 @@ This interface has no functions.
## [% if enum.is_flags %]Flags[% else %]Values[% endif %]
[% for k, value in enum['values'].items() %]
<a name="[[value.name]]"></a><span style="font-size: medium;">**<code markdown="span">[[(enum.name + value.name) | to_macro_case]]</code>**&nbsp;&nbsp;&mdash;&nbsp;&nbsp;[% if enum.is_flags %]0x[['%08x' | format(value.value)]][% else %][[value.value]][% endif %]</span>
<a name="[[value.name]]"></a><span style="font-size: medium;">**<code markdown="span">[[enum.name | to_macro_case]]_[[value.name]]</code>**&nbsp;&nbsp;&mdash;&nbsp;&nbsp;[% if enum.is_flags %]0x[['%08x' | format(value.value)]][% else %][[value.value]][% endif %]</span>
[[-status_badge(value.status)]]
<ul markdown="block">

View File

@@ -624,6 +624,7 @@ for _, item in list(interfaces.items()):
toplevel_interfaces = []
for k, item in list(interfaces.items()):
k = split_name(k)
item.parent = None
if len(k) == 1:
toplevel_interfaces.append(item)
else:
@@ -673,36 +674,49 @@ def tokenize(text, interface, interface_transform, value_type_transform, attribu
and returns a string.
value_type_transform: A function that takes a value type object as an argument
and returns a string.
attribute_transform: A function that takes the token strin and an attribute
object as arguments and returns a string.
attribute_transform: A function that takes the token string, an interface object
and an attribute object as arguments and returns a string.
"""
if text is None or isinstance(text, jinja2.runtime.Undefined):
return text
def token_transform(token):
token = token.groups()[0]
if ':' in token:
intf_name, _, attr_name = token.partition(':')
intf = InterfaceRefElement(interface.fullname, None, intf_name, []).resolve()
token = attr_name
else:
intf = interface
token_list = split_name(token)
# Check if this is an attribute reference
scope = interface
scope = intf
attr = None
while attr is None and not scope is None:
attr_intf = scope
for name in token_list:
if not name in attr_intf['attributes']:
attr = None
break
attr = attr_intf['attributes'][name]
attr_intf = attr['type']
scope = scope.get('parent', None)
for name in token_list:
if scope.fullname == 'ODrive': # TODO: this is a temporary hack
scope = interfaces['ODrive3']
if (not name.endswith('()')) and name in scope.get_all_attributes():
attr = scope.get_all_attributes()[name]
scope = attr['type']
elif name.endswith('()') and name[:-2] in scope.get_all_functions():
attr = scope.get_all_functions()[name[:-2]]
scope = None # TODO
else:
print('Warning: cannot resolve "{}" in {}'.format(token, intf.fullname))
return "`" + token + "`"
if not attr is None:
return attribute_transform(token, attr)
return attribute_transform(token, interface, intf, attr)
print('Warning: cannot resolve "{}" in {}'.format(token, interface.fullname))
return "`" + token + "`"
return re.sub(r'`([A-Za-z\._]+)`', token_transform, text)
return re.sub(r'`([A-Za-z0-9\.:_]+)`', token_transform, text)
def html_escape(text):
import html
return html.escape(str(text))
env.filters['to_pascal_case'] = to_pascal_case
env.filters['to_camel_case'] = to_camel_case
@@ -713,6 +727,7 @@ env.filters['first'] = lambda x: next(iter(x))
env.filters['skip_first'] = lambda x: list(x)[1:]
env.filters['to_c_string'] = lambda x: '\n'.join(('"' + line.replace('"', '\\"') + '"') for line in json.dumps(x, separators=(',', ':')).replace('{"name"', '\n{"name"').split('\n'))
env.filters['tokenize'] = tokenize
env.filters['html_escape'] = html_escape
env.filters['diagonalize'] = lambda lst: [lst[:i + 1] for i in range(len(lst))]
env.filters['debug'] = lambda x: print(x)