Skip to content

Commit

Permalink
[wpilib] Pregenerate PWM motor controllers (wpilibsuite#6742)
Browse files Browse the repository at this point in the history
Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com>
  • Loading branch information
pjreiniger and Gold856 authored Jun 18, 2024
1 parent 66c0abb commit b6bd798
Show file tree
Hide file tree
Showing 49 changed files with 790 additions and 271 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/pregenerate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
run: ./wpimath/generate_numbers.py && ./wpimath/generate_quickbuf.py --quickbuf_plugin=protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
- name: Run HIDs
run: ./wpilibj/generate_hids.py && ./wpilibc/generate_hids.py && ./wpilibNewCommands/generate_hids.py
- name: Run PWM Controllers
run: ./wpilibj/generate_pwm_motor_controllers.py && ./wpilibc/generate_pwm_motor_controllers.py
- name: Add untracked files to index so they count as changes
run: git add -A
- name: Check output
Expand Down
101 changes: 101 additions & 0 deletions wpilibc/generate_pwm_motor_controllers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python3

# Copyright (c) FIRST and other WPILib contributors.
# Open Source Software; you can modify and/or share it under the terms of
# the WPILib BSD license file in the root directory of this project.
import argparse
import json
import sys
import os
from typing import Dict, Any
from pathlib import Path

from jinja2 import Environment, FileSystemLoader
from jinja2.environment import Template


def render_template(
template: Template, output_dir: Path, filename: str, controller: Dict[str, Any]
):
output_dir.mkdir(parents=True, exist_ok=True)

output_file = output_dir / filename
output_file.write_text(template.render(controller), encoding="utf-8")


def generate_cpp_headers(
output_root: Path, template_root: Path, pwm_motor_controllers: Dict[str, Any]
):
header_template_root = template_root / "main/native/include/frc/motorcontroller"
env = Environment(
loader=FileSystemLoader(header_template_root),
autoescape=False,
keep_trailing_newline=True,
)

root_path = output_root / "main/native/include/frc/motorcontrol"
template = env.get_template("pwm_motor_controller.h.jinja")

for controller in pwm_motor_controllers:
controller_name = os.path.basename(f"{controller['name']}.h")
render_template(template, root_path, controller_name, controller)


def generate_cpp_sources(output_root, template_root, pwm_motor_controllers):
cpp_template_root = str(template_root / "main/native/cpp/motorcontroller")
env = Environment(
loader=FileSystemLoader(cpp_template_root),
autoescape=False,
keep_trailing_newline=True,
)

root_path = output_root / "main/native/cpp/motorcontrol"
template = env.get_template("pwm_motor_controller.cpp.jinja")

for controller in pwm_motor_controllers:
controller_name = os.path.basename(f"{controller['name']}.cpp")
render_template(template, root_path, controller_name, controller)


def generate_pwm_motor_controllers(
output_root: Path, template_root: Path, schema_root: Path
):
with (schema_root / "pwm_motor_controllers.json").open(encoding="utf-8") as f:
controllers = json.load(f)

generate_cpp_headers(output_root, template_root, controllers)
generate_cpp_sources(output_root, template_root, controllers)


def main(argv):
script_path = Path(__file__).resolve()
dirname = script_path.parent

parser = argparse.ArgumentParser()
parser.add_argument(
"--output_directory",
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
default=dirname / "src/generated",
type=Path,
)
parser.add_argument(
"--schema_root",
help="Optional. If set, will use this directory as the root for discovering the pwm controller schema",
default=dirname / "../wpilibj/src/generate",
type=Path,
)
parser.add_argument(
"--template_root",
help="Optional. If set, will use this directory as the root for the jinja templates",
default=dirname / "src/generate",
type=Path,
)
args = parser.parse_args(argv)

generate_pwm_motor_controllers(
args.output_directory, args.template_root, args.schema_root
)


if __name__ == "__main__":
main(sys.argv[1:])
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_pwm_motor_controllers.py. DO NOT MODIFY

#include "frc/motorcontrol/{{ name }}.h"

#include <hal/FRCUsageReporting.h>

using namespace frc;

{{ name }}::{{ name }}(int channel) : PWMMotorController("{{ name }}", channel) {
m_pwm.SetBounds({{ pulse_width_ms.max }}_ms, {{ pulse_width_ms.deadbandMax }}_ms, {{ pulse_width_ms.center }}_ms, {{ pulse_width_ms.deadbandMin }}_ms, {{ pulse_width_ms.min }}_ms);
m_pwm.SetPeriodMultiplier(PWM::kPeriodMultiplier_{{ PeriodMultiplier | default("1", true)}}X);
m_pwm.SetSpeed(0.0);
m_pwm.SetZeroLatch();

HAL_Report(HALUsageReporting::kResourceType_{{ ResourceName }}, GetChannel() + 1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_pwm_motor_controllers.py. DO NOT MODIFY

#pragma once

#include "frc/motorcontrol/PWMMotorController.h"

namespace frc {

/**
* {{ Manufacturer }} {{ DisplayName }} Motor Controller with PWM control.
*
* Note that the {{ DisplayName }} uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the {{ DisplayName }} User
* Manual available from {{ Manufacturer }}.
*
* \li {{ "{:.3f}".format(pulse_width_ms.max) }}ms = full "forward"
* \li {{ "{:.3f}".format(pulse_width_ms.deadbandMax) }}ms = the "high end" of the deadband range
* \li {{ "{:.3f}".format(pulse_width_ms.center) }}ms = center of the deadband range (off)
* \li {{ "{:.3f}".format(pulse_width_ms.deadbandMin) }}ms = the "low end" of the deadband range
* \li {{ "{:.3f}".format(pulse_width_ms.min) }}ms = full "reverse"
*/
class {{ name }} : public PWMMotorController {
public:
/**
* Constructor for a {{ DisplayName }} connected via PWM.
*
* @param channel The PWM channel that the {{ DisplayName }} is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
*/
explicit {{ name }}(int channel);

{{ name }}({{ name }}&&) = default;
{{ name }}& operator=({{ name }}&&) = default;
};

} // namespace frc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b6bd798

Please sign in to comment.