API Reference

transmissions.cli

Command-line interface for transmissions.

The CLI supports the existing universal-transmission analysis workflow and adds one documentation helper:

  1. Existing analyzer workflow:

    python -m transmissions.cli --spec transmissions/in/spec.json --schedule transmissions/in/schedule.json
    
  2. Sphinx documentation skeleton generation:

    python -m transmissions.cli sphinx-skel transmissions/docs
    

The sphinx-skel command generates conservative, GitHub Pages friendly Sphinx files while preserving the historical no-subcommand analyzer interface.

transmissions.cli.build_parser()[source]

Build the historical no-subcommand analyzer parser.

Return type:

ArgumentParser

transmissions.cli.build_sphinx_parser()[source]

Build the parser for the sphinx-skel helper.

Return type:

ArgumentParser

transmissions.cli.main(argv=None)[source]

Run the transmissions command-line interface.

Parameters:

argv (list[str] | None)

Return type:

int

transmissions.apis

transmissions.apis.apply_cli_overrides_to_spec(spec_data, overrides)[source]
Parameters:
  • spec_data (Mapping[str, Any])

  • overrides (Mapping[str, Any] | None)

Return type:

dict[str, Any]

transmissions.apis.apply_preset_to_spec(spec_data, preset_name)[source]
Parameters:
  • spec_data (Mapping[str, Any])

  • preset_name (str | None)

Return type:

dict[str, Any]

transmissions.apis.build_transmission(*, spec_data, schedule_data, preset=None, overrides=None)[source]
Parameters:
  • spec_data (Mapping[str, Any])

  • schedule_data (Mapping[str, Any])

  • preset (str | None)

  • overrides (Mapping[str, Any] | None)

Return type:

GenericTransmission

transmissions.apis.list_presets(spec_data)[source]
Parameters:

spec_data (Mapping[str, Any])

Return type:

list[str]

transmissions.app

class transmissions.app.RunRequest(spec_path: 'str | None' = None, schedule_path: 'str | None' = None, preset: 'str | None' = None, state: 'str | None' = None, input_speed: 'float | None' = None, show_speeds: 'bool' = False, ratios_only: 'bool' = False, show_topology: 'bool' = False, as_json: 'bool' = False, output_json: 'str | None' = None, overrides: 'dict[str, Any] | None' = None)[source]

Bases: object

Parameters:
  • spec_path (str | None)

  • schedule_path (str | None)

  • preset (str | None)

  • state (str | None)

  • input_speed (float | None)

  • show_speeds (bool)

  • ratios_only (bool)

  • show_topology (bool)

  • as_json (bool)

  • output_json (str | None)

  • overrides (dict[str, Any] | None)

as_json: bool = False
input_speed: float | None = None
output_json: str | None = None
overrides: dict[str, Any] | None = None
preset: str | None = None
ratios_only: bool = False
schedule_path: str | None = None
show_speeds: bool = False
show_topology: bool = False
spec_path: str | None = None
state: str | None = None
class transmissions.app.TransmissionApplication[source]

Bases: object

run(req)[source]
Parameters:

req (RunRequest)

Return type:

dict[str, Any]

transmissions.app.render_text_report(payload, *, show_speeds=False, ratios_only=False)[source]
Parameters:
  • payload (Mapping[str, Any])

  • show_speeds (bool)

  • ratios_only (bool)

Return type:

str

transmissions.io

transmissions.io.load_json(path)[source]
Parameters:

path (str | None)

Return type:

dict[str, Any]

transmissions.io.save_json(payload, path)[source]
Parameters:
  • payload (dict[str, Any])

  • path (str | None)

Return type:

None

transmissions.model

class transmissions.model.BrakeSpec(name: 'str', member: 'str')[source]

Bases: object

Parameters:
  • name (str)

  • member (str)

member: str
name: str
class transmissions.model.ClutchSpec(name: 'str', a: 'str', b: 'str')[source]

Bases: object

Parameters:
  • name (str)

  • a (str)

  • b (str)

a: str
b: str
name: str
class transmissions.model.GearsetSpec(name: 'str', Ns: 'int', Nr: 'int', sun: 'str', ring: 'str', carrier: 'str')[source]

Bases: object

Parameters:
  • name (str)

  • Ns (int)

  • Nr (int)

  • sun (str)

  • ring (str)

  • carrier (str)

Nr: int
Ns: int
carrier: str
name: str
ring: str
sun: str
class transmissions.model.GenericSolveResult(state: 'str', engaged: 'tuple[str, ...]', ok: 'bool', ratio: 'float | None', speeds: 'dict[str, float]', notes: 'str' = '', solver_path: 'str' = 'core_generic_json_builder', status: 'str' = 'ok', message: 'str' = '')[source]

Bases: object

Parameters:
  • state (str)

  • engaged (tuple[str, ...])

  • ok (bool)

  • ratio (float | None)

  • speeds (dict[str, float])

  • notes (str)

  • solver_path (str)

  • status (str)

  • message (str)

engaged: tuple[str, ...]
message: str = ''
notes: str = ''
ok: bool
ratio: float | None
solver_path: str = 'core_generic_json_builder'
speeds: dict[str, float]
state: str
status: str = 'ok'
class transmissions.model.GenericTransmission(*, spec, schedule)[source]

Bases: object

Parameters:
available_states()[source]
Return type:

list[str]

build_solver()[source]
Return type:

tuple[TransmissionSolver, dict[str, RotatingMember], dict[str, Clutch], dict[str, Brake], dict[str, Sprag]]

normalize_state_name(state)[source]
Parameters:

state (str)

Return type:

str

solve(*, state, input_speed=1.0)[source]
Parameters:
  • state (str)

  • input_speed (float)

Return type:

dict[str, GenericSolveResult]

solve_state(state, *, input_speed=1.0)[source]
Parameters:
  • state (str)

  • input_speed (float)

Return type:

GenericSolveResult

topology_summary()[source]
Return type:

dict[str, Any]

class transmissions.model.ShiftSchedule(states: 'dict[str, ShiftStateSpec]', notes: 'str' = '', display_order: 'list[str]' = <factory>)[source]

Bases: object

Parameters:
  • states (dict[str, ShiftStateSpec])

  • notes (str)

  • display_order (list[str])

display_order: list[str]
static from_dict(data, *, aliases=None)[source]
Parameters:
  • data (Mapping[str, Any])

  • aliases (Mapping[str, str] | None)

Return type:

ShiftSchedule

notes: str = ''
states: dict[str, ShiftStateSpec]
class transmissions.model.ShiftStateSpec(name: 'str', active_constraints: 'tuple[str, ...]', display_elements: 'tuple[str, ...]', notes: 'str' = '', manual_neutral: 'bool' = False)[source]

Bases: object

Parameters:
  • name (str)

  • active_constraints (tuple[str, ...])

  • display_elements (tuple[str, ...])

  • notes (str)

  • manual_neutral (bool)

active_constraints: tuple[str, ...]
display_elements: tuple[str, ...]
manual_neutral: bool = False
name: str
notes: str = ''
class transmissions.model.SpragSpec(name: 'str', member: 'str', hold_direction: 'str' = 'counter_clockwise', locked_when_engaged: 'bool' = True)[source]

Bases: object

Parameters:
  • name (str)

  • member (str)

  • hold_direction (str)

  • locked_when_engaged (bool)

hold_direction: str = 'counter_clockwise'
locked_when_engaged: bool = True
member: str
name: str
class transmissions.model.TransmissionSpec(name: 'str', input_member: 'str', output_member: 'str', gearsets: 'list[GearsetSpec]', clutches: 'list[ClutchSpec]', brakes: 'list[BrakeSpec]', sprags: 'list[SpragSpec]' = <factory>, permanent_ties: 'list[tuple[str, str]]' = <factory>, members: 'list[str]' = <factory>, display_order: 'list[str]' = <factory>, state_aliases: 'dict[str, str]' = <factory>, speed_display_order: 'list[str]' = <factory>, speed_display_labels: 'dict[str, str]' = <factory>, strict_geometry: 'bool' = False, notes: 'str' = '', presets: 'dict[str, Any]' = <factory>, meta: 'dict[str, Any]' = <factory>)[source]

Bases: object

Parameters:
  • name (str)

  • input_member (str)

  • output_member (str)

  • gearsets (list[GearsetSpec])

  • clutches (list[ClutchSpec])

  • brakes (list[BrakeSpec])

  • sprags (list[SpragSpec])

  • permanent_ties (list[tuple[str, str]])

  • members (list[str])

  • display_order (list[str])

  • state_aliases (dict[str, str])

  • speed_display_order (list[str])

  • speed_display_labels (dict[str, str])

  • strict_geometry (bool)

  • notes (str)

  • presets (dict[str, Any])

  • meta (dict[str, Any])

all_member_names()[source]
Return type:

list[str]

brakes: list[BrakeSpec]
clutches: list[ClutchSpec]
display_order: list[str]
static from_dict(data)[source]
Parameters:

data (Mapping[str, Any])

Return type:

TransmissionSpec

gearsets: list[GearsetSpec]
input_member: str
members: list[str]
meta: dict[str, Any]
name: str
notes: str = ''
output_member: str
permanent_ties: list[tuple[str, str]]
presets: dict[str, Any]
speed_display_labels: dict[str, str]
speed_display_order: list[str]
sprags: list[SpragSpec]
state_aliases: dict[str, str]
strict_geometry: bool = False

transmissions.utils

exception transmissions.utils.TransmissionAppError[source]

Bases: RuntimeError

transmissions.utils.coerce_int(value, *, context)[source]
Parameters:
  • value (Any)

  • context (str)

Return type:

int

transmissions.utils.dedupe_keep_order(items)[source]
Parameters:

items (Iterable[str])

Return type:

list[str]

transmissions.utils.ensure_dict(value, *, context)[source]
Parameters:
  • value (Any)

  • context (str)

Return type:

dict[str, Any]

transmissions.utils.ensure_list(value, *, context)[source]
Parameters:
  • value (Any)

  • context (str)

Return type:

list[Any]

transmissions.utils.ensure_str(value, *, context)[source]
Parameters:
  • value (Any)

  • context (str)

Return type:

str

transmissions.utils.maybe_float(value)[source]
Parameters:

value (Any)

Return type:

float | None

transmissions.utils.normalize_state_name(name, aliases=None)[source]
Parameters:
  • name (str)

  • aliases (Mapping[str, str] | None)

Return type:

str

transmissions.utils.parse_key_value_overrides(items)[source]
Parameters:

items (list[str] | None)

Return type:

dict[str, Any]

transmissions.utils.stable_json_dumps(obj)[source]
Parameters:

obj (Any)

Return type:

str

transmissions.core.clutch

transmissions.core.clutch

Core shift-element abstractions for transmission kinematics.

This Core V2 upgrade keeps the original project concepts: - RotatingMember - Ground / GROUND - Constraint - Clutch - Brake

and adds: - OneWayClutch / Sprag - richer summaries / diagnostics - explicit naming and validation - backward-friendly behavior for all existing transmission scripts

Design note

These classes are intentionally kinematic. They express idealized speed constraints such as:

clutch engaged -> w_a = w_b brake engaged -> w_member = 0

The new OneWayClutch class provides a core abstraction for a sprag / overrunning clutch, but it does not by itself solve torque-direction logic. In current Core V2 it mainly serves as: - a first-class topology object - a brake-like kinematic hold when engaged in a specified direction - metadata for future richer state logic

class transmissions.core.clutch.Brake(member, name=None)[source]

Bases: Constraint

Locks a rotating member to ground when engaged.

Kinematic meaning:

w_member = 0

Parameters:
constraint()[source]
Return type:

Tuple[RotatingMember, Ground] | None

summary_dict()[source]
Return type:

Dict[str, Any]

class transmissions.core.clutch.Clutch(member_a, member_b, name=None)[source]

Bases: Constraint

Locks two rotating members together when engaged.

Kinematic meaning:

w_a = w_b

Parameters:
constraint()[source]

Return the active equality constraint, if engaged.

Return type:

tuple(member_a, member_b) or None

summary_dict()[source]
Return type:

Dict[str, Any]

exception transmissions.core.clutch.ClutchError[source]

Bases: ValueError

User-facing clutch / constraint modeling error.

class transmissions.core.clutch.Constraint(name=None)[source]

Bases: object

Base class for shift elements / kinematic constraints.

State

  • engaged = True -> constraint active

  • engaged = False -> constraint inactive

constraint()[source]
engage()[source]
Return type:

None

is_engaged()[source]
Return type:

bool

release()[source]
Return type:

None

set_engaged(value)[source]
Parameters:

value (bool)

Return type:

None

summary_dict()[source]
Return type:

Dict[str, Any]

Parameters:

name (Optional[str])

class transmissions.core.clutch.Ground(name='ground')[source]

Bases: object

Ground / housing sentinel used in brake constraints.

Parameters:

name (str)

name: str = 'ground'
class transmissions.core.clutch.OneWayClutch(member, *, hold_direction='unknown', locked_when_engaged=True, name=None)[source]

Bases: Constraint

One-way clutch / overrunning clutch / sprag abstraction.

Current Core V2 behavior

In current kinematic usage, when engaged this behaves like a directional hold of one member relative to ground:

w_member = 0

but it also records the intended hold direction so higher-level logic can distinguish between: - a regular brake - a sprag / one-way clutch

param member:

Member being held when the one-way element is active in its holding mode.

param hold_direction:

Metadata describing the holding direction. Examples: - “negative” - “counter_clockwise” - “ccw” - “reverse”

The solver does not yet infer engagement from torque direction. This is reserved for future richer state logic.

param locked_when_engaged:

If True (default), .constraint() returns a brake-like ground relation when engaged. If False, the object becomes pure metadata unless a future solver interprets it.

constraint()[source]

Return the active hold constraint, if engaged and configured to lock.

Return type:

tuple(member, GROUND) or None

holds_direction(direction)[source]

Return True if the stored hold direction matches the queried one.

Parameters:

direction (str)

Return type:

bool

summary_dict()[source]
Return type:

Dict[str, Any]

Parameters:
  • member (RotatingMember)

  • hold_direction (str)

  • locked_when_engaged (bool)

  • name (Optional[str])

class transmissions.core.clutch.RotatingMember(name, notes='')[source]

Bases: object

Kinematic rotating member.

Examples

  • sun gear

  • ring gear

  • carrier

  • output shaft

  • intermediate node

Parameters:
  • name (str)

  • notes (str)

name: str
notes: str = ''
summary_dict()[source]
Return type:

Dict[str, Any]

class transmissions.core.clutch.Sprag(member, *, hold_direction='counter_clockwise', locked_when_engaged=True, name=None)[source]

Bases: OneWayClutch

Thin alias/subclass for a transmission sprag.

Defaults to a counter-clockwise / negative-direction hold convention, but the caller can override it explicitly.

Parameters:
  • member (RotatingMember)

  • hold_direction (str)

  • locked_when_engaged (bool)

  • name (Optional[str])

transmissions.core.planetary

Core simple-planetary kinematic model.

This module implements a compact simple-planetary gearset model used by the transmission kinematic solver.

The linear Willis relation is represented as:

Ns * (omega_s - omega_c) + Nr * (omega_r - omega_c) = 0

An equivalent ratio form is:

(omega_s - omega_c) / (omega_r - omega_c) = -Nr / Ns

The module separates kinematics from strict geometry validation. This allows widely cited transmission reference tooth counts to be analyzed in relaxed mode even when they do not satisfy the standard integer-planet check for a basic simple planetary construction.

Compatibility notes

The public attributes sun, ring, and carrier remain RotatingMember objects because solver.py and other project modules access the .name attribute on those members.

class transmissions.core.planetary.GearGeometry(label, teeth)[source]

Bases: object

Metadata for a toothed member.

Parameters:
  • label (str)

  • teeth (int)

label: str
teeth: int
class transmissions.core.planetary.PlanetaryGearSet(Ns, Nr, name='PGS', sun=None, ring=None, carrier=None, geometry_mode='relaxed')[source]

Bases: object

Represent a simple planetary gearset.

Parameters:
  • Ns (int) – Sun tooth count.

  • Nr (int) – Ring tooth count.

  • name (str) – Name of the gearset.

  • sun (Optional[RotatingMember]) – Optional injected sun rotating member for compound architectures.

  • ring (Optional[RotatingMember]) – Optional injected ring rotating member for compound architectures.

  • carrier (Optional[RotatingMember]) – Optional injected carrier rotating member for compound architectures.

  • geometry_mode (str) – Geometry-validation mode. Use "relaxed" for kinematics-only analysis or "strict" to require standard integer-planet simple planetary geometry.

Notes

For a standard simple planetary with one planet meshing the sun and ring, the implied planet tooth count is:

Np = (Nr - Ns) / 2

In relaxed mode this value is recorded but not enforced. In strict mode it must be a positive integer.

VALID_GEOMETRY_MODES = {'relaxed', 'strict'}
describe_mode(input_member, output_member, fixed_member, input_speed=1.0)[source]

Return a qualitative classification for the solved ratio.

Parameters:
  • input_member (str)

  • output_member (str)

  • fixed_member (str)

  • input_speed (float)

Return type:

str

classmethod geometry_report(*, Ns, Nr, mode='relaxed')[source]

Return a non-throwing geometry report for proposed tooth counts.

Parameters:
  • Ns (int)

  • Nr (int)

  • mode (str)

Return type:

PlanetaryGeometryReport

property has_integer_planet_count: bool

Return whether the implied planet tooth count is a positive integer.

property is_geometry_strict_valid: bool

Return whether the current tooth counts pass strict validation.

planetary_equation(ws, wr, wc)[source]

Return the residual of the linear Willis planetary constraint.

Parameters:
  • ws (float)

  • wr (float)

  • wc (float)

Return type:

float

ratio(input_member, output_member, fixed_member, input_speed=1.0)[source]

Return the speed ratio omega_in / omega_out.

Parameters:
  • input_member (str)

  • output_member (str)

  • fixed_member (str)

  • input_speed (float)

Return type:

float

solve(input_member, output_member, fixed_member, input_speed=1.0)[source]

Solve one input, one output, and one fixed member.

Parameters:
  • input_member (str) – Input member name. Must be one of "sun", "ring", or "carrier".

  • output_member (str) – Output member name. Must be one of "sun", "ring", or "carrier".

  • fixed_member (str) – Fixed member name. Must be one of "sun", "ring", or "carrier".

  • input_speed (float) – Input angular speed.

Returns:

Speeds for sun, ring, and carrier.

Return type:

dict[str, float]

summary(input_member, output_member, fixed_member, input_speed=1.0)[source]

Print a standalone human-readable summary.

Parameters:
  • input_member (str)

  • output_member (str)

  • fixed_member (str)

  • input_speed (float)

Return type:

None

validate_geometry(*, strict=None, raise_on_error=False)[source]

Validate gear geometry and return a report.

Parameters:
  • strict (bool | None) –

    Validation mode override.

    • True enforces standard integer-planet simple planetary geometry.

    • False applies relaxed validation with kinematic sanity checks only.

    • None uses this instance’s geometry_mode.

  • raise_on_error (bool) – Raise ValueError when the geometry is invalid.

Return type:

PlanetaryGeometryReport

willis_ratio(ws, wr, wc)[source]

Return the Willis ratio (ws - wc) / (wr - wc).

Parameters:
  • ws (float)

  • wr (float)

  • wc (float)

Return type:

float

class transmissions.core.planetary.PlanetaryGeometryReport(ok, mode, Ns, Nr, delta, Np_exact, Np_integer, messages=())[source]

Bases: object

Validation and metadata report for a simple planetary gearset.

Parameters:
  • ok (bool)

  • mode (str)

  • Ns (int)

  • Nr (int)

  • delta (int)

  • Np_exact (float)

  • Np_integer (int | None)

  • messages (tuple[str, ...])

Np_exact: float
Np_integer: int | None
Nr: int
Ns: int
delta: int
messages: tuple[str, ...] = ()
mode: str
ok: bool
property strict_ok: bool

Return True when the report passed strict-geometry validation.

transmissions.core.shaft

transmissions.core.shaft

Core shaft / rotating-node abstractions for transmission kinematics.

Why this file exists

The first version of the transmissions app modeled rotating members directly (sun, ring, carrier, etc.) but did not provide a clean abstraction for the shaft node that ties several physical members together.

Real automatic transmissions often have situations like:

  • front carrier = output shaft = rear ring

  • front sun = rear sun (common sun)

  • node23 = PG2 carrier = PG3 ring

  • input shaft connected to several members through clutches_brakes_flywheels

Those are not “new gears”; they are the same rotating node seen by multiple components. This module provides a simple, explicit representation for that.

Design goals

  • lightweight and solver-friendly

  • no heavy geometry assumptions

  • compatible with the existing RotatingMember concept used elsewhere

  • useful for topology definition, reporting, and equation assembly

  • able to emit symbolic equality constraints for permanent member ties

Key classes

  • ShaftNode

    A rotating node / shaft station with one angular speed shared by all attached members.

  • MemberAttachment

    Metadata linking a named physical member (e.g. PG1.carrier) to a node.

Typical use

output = ShaftNode(“output”) output.attach(“PG1.carrier”) output.attach(“PG2.ring”) output.attach(“output_shaft”)

sun_common = ShaftNode(“sun_common”) sun_common.attach(“PG1.sun”) sun_common.attach(“PG2.sun”)

Then a higher-level solver can assert that all attachments to the same node share one rotational speed.

class transmissions.core.shaft.MemberAttachment(member_name, role='', notes='')[source]

Bases: object

A physical member attached to a shaft node.

Parameters:
  • member_name (str) – Human-readable identifier such as PG1.carrier, rear_ring, etc.

  • role (str) – Optional role descriptor such as output, sun, carrier, ring.

  • notes (str) – Optional free-form notes.

member_name: str
notes: str = ''
role: str = ''
exception transmissions.core.shaft.ShaftError[source]

Bases: ValueError

User-facing shaft / node modeling error.

class transmissions.core.shaft.ShaftNode(name, is_ground=False, speed_symbol_name=None, notes='')[source]

Bases: object

A rotating shaft/node to which one or more physical members are permanently attached.

Conceptually, every attached member rotates at the same angular speed.

Parameters:
  • name (str) – Node name, e.g. input, output, sun_common, node12.

  • is_ground (bool) – If True, this node is permanently grounded (speed = 0).

  • speed_symbol_name (str | None) – Optional explicit symbolic variable name. If omitted, a name is derived from name.

  • notes (str) – Optional descriptive notes.

Notes

This class is intentionally kinematic, not geometric. It does not care about tooth counts or physical packaging.

attach(member_name, *, role='', notes='')[source]

Attach a physical member name to this node.

Raises:

ShaftError – If the member is already attached to this node.

Parameters:
  • member_name (str)

  • role (str)

  • notes (str)

Return type:

MemberAttachment

property attachment_names: tuple[str, ...]

Names of all attached members.

property attachments: tuple[MemberAttachment, ...]

Immutable view of attachments.

clear_attachments()[source]

Remove all attachments from this node.

Return type:

None

detach(member_name)[source]

Detach a member by name.

Parameters:

member_name (str)

Return type:

None

equality_equation(other)[source]

Return a symbolic equality equation enforcing equal speed between nodes.

Useful when two nodes are permanently tied.

Parameters:

other (ShaftNode)

Return type:

sympy.Expr

ground_equation()[source]

Return the grounding equation for this node.

Returns:

w_node if grounded; otherwise raises.

Return type:

sympy.Expr

has_attachment(member_name)[source]

Return True if member_name is attached to this node.

Parameters:

member_name (str)

Return type:

bool

is_ground: bool = False
name: str
notes: str = ''
property speed_symbol: sympy.Symbol

SymPy symbol representing the angular speed of this node.

Ground nodes still get a symbol for consistency, but higher-level equation builders will typically constrain it to zero.

speed_symbol_name: str | None = None
summary_dict()[source]

Structured summary for logging / JSON.

Return type:

dict

summary_text()[source]

Human-readable one-node summary.

Return type:

str

transmissions.core.shaft.build_node(name, *members, is_ground=False, notes='')[source]

Convenience factory for a node with multiple attachments.

Example

output = build_node(“output”, “PG1.carrier”, “PG2.ring”, “output_shaft”)

Parameters:
  • name (str)

  • members (str)

  • is_ground (bool)

  • notes (str)

Return type:

ShaftNode

transmissions.core.shaft.permanent_tie_equations(nodes)[source]

Build equality equations tying all listed nodes to the first node.

Example

permanent_tie_equations([node_a, node_b, node_c]) -> [w_a - w_b, w_a - w_c]

Notes

In many cases you will not need this if several physical members are modeled directly as a single ShaftNode. This helper is for situations where separate nodes were created first and later discovered to be tied.

Parameters:

nodes (Sequence[ShaftNode])

Return type:

List[sympy.Expr]

transmissions.core.shaft.summarize_nodes(nodes)[source]

Return structured summaries for a collection of nodes.

Parameters:

nodes (Iterable[ShaftNode])

Return type:

List[dict]

transmissions.core.solver

transmissions.core.solver

Core V2 transmission kinematic solver.

This module upgrades the original solver by adding:

  • linear Willis/simple-planetary equations

  • permanent member ties

  • optional shaft-node equality constraints

  • better solve classification

  • cleaner diagnostics for underdetermined / inconsistent systems

  • backward-friendly support for the existing component classes

Design intent

This solver is still kinematic only. It solves angular-speed relationships for:

  • rotating members

  • planetary gearsets

  • clutches_brakes_flywheels

  • brakes

  • permanent equalities (e.g. front carrier = rear ring = output)

  • optional shaft-node equalities

It is designed to become the common engine behind specific transmission scripts such as Simpson, Ravigneaux, Allison 6-speed, Ford C4, etc.

exception transmissions.core.solver.DuplicateMemberError[source]

Bases: TransmissionSolverError

Raised when duplicate member names are added.

exception transmissions.core.solver.InconsistentSystemError[source]

Bases: TransmissionSolverError

Raised when the equation system has no solution.

class transmissions.core.solver.SolveClassification(status, message='')[source]

Bases: object

Human-readable solve classification.

status:

One of: - ok - underdetermined - inconsistent

Parameters:
  • status (str)

  • message (str)

message: str = ''
property ok: bool
status: str
class transmissions.core.solver.SolveReport(ok, classification, member_speeds=<factory>, raw_solution=None, equations=<factory>, symbols=<factory>, engaged_clutches=(), engaged_brakes=(), permanent_ties=(), input_member=None, input_speed=None, notes='')[source]

Bases: object

Structured solver result/report.

Parameters:
  • ok (bool)

  • classification (SolveClassification)

  • member_speeds (Dict[str, float])

  • raw_solution (dict | None)

  • equations (List[sympy.Expr])

  • symbols (Dict[str, sympy.Symbol])

  • engaged_clutches (Tuple[str, ...])

  • engaged_brakes (Tuple[str, ...])

  • permanent_ties (Tuple[Tuple[str, str], ...])

  • input_member (str | None)

  • input_speed (float | None)

  • notes (str)

classification: SolveClassification
engaged_brakes: Tuple[str, ...] = ()
engaged_clutches: Tuple[str, ...] = ()
equations: List[sympy.Expr]
input_member: str | None = None
input_speed: float | None = None
member_speeds: Dict[str, float]
notes: str = ''
ok: bool
permanent_ties: Tuple[Tuple[str, str], ...] = ()
raw_solution: dict | None = None
symbols: Dict[str, sympy.Symbol]
to_dict()[source]
Return type:

dict

class transmissions.core.solver.TransmissionSolver[source]

Bases: object

Kinematic solver for transmission systems.

Core capabilities

  • add rotating members

  • add simple planetary gearsets

  • add clutches_brakes_flywheels and brakes

  • add permanent equalities between members

  • optionally add shaft nodes and tie them by speed

  • solve with a specified input member and speed

Backward compatibility

The existing project uses:

add_member() add_gearset() add_clutch() add_brake() solve(input_member, input_speed)

Those are preserved.

active_constraint_names()[source]
Return type:

Dict[str, Tuple[str, …]]

add_brake(brake)[source]
Parameters:

brake (Brake)

Return type:

None

add_clutch(clutch)[source]
Parameters:

clutch (Clutch)

Return type:

None

add_gearset(gearset)[source]
Parameters:

gearset (PlanetaryGearSet)

Return type:

None

add_member(member)[source]
Parameters:

member (RotatingMember)

Return type:

None

add_members(members)[source]
Parameters:

members (Iterable[RotatingMember])

Return type:

None

add_node(node)[source]
Parameters:

node (ShaftNode)

Return type:

None

add_node_tie(node_a, node_b)[source]
Parameters:
Return type:

None

add_permanent_tie(member_a, member_b)[source]
Parameters:
Return type:

None

build_equations(*, input_member, input_speed=1.0, include_nodes=False)[source]
Parameters:
  • input_member (str)

  • input_speed (float)

  • include_nodes (bool)

Return type:

Tuple[List[sympy.Expr], Dict[str, sympy.Symbol]]

clear_permanent_ties()[source]
Return type:

None

release_all()[source]
Return type:

None

solve(input_member, input_speed=1.0, *, allow_underdetermined=False, include_nodes=False)[source]
Parameters:
  • input_member (str)

  • input_speed (float)

  • allow_underdetermined (bool)

  • include_nodes (bool)

Return type:

Dict[str, float]

solve_report(input_member, input_speed=1.0, *, include_nodes=False)[source]
Parameters:
  • input_member (str)

  • input_speed (float)

  • include_nodes (bool)

Return type:

SolveReport

summary_dict()[source]
Return type:

dict

exception transmissions.core.solver.TransmissionSolverError[source]

Bases: RuntimeError

Base solver error.

exception transmissions.core.solver.UnderdeterminedSystemError[source]

Bases: TransmissionSolverError

Raised when a solve exists but does not determine all tracked members.

exception transmissions.core.solver.UnknownMemberError[source]

Bases: TransmissionSolverError

Raised when a required member is missing.

transmissions.module_loader

transmissions.module_loader.load_local_module(module_name, filename)[source]

Load a sibling .py file as a module under a safe synthetic name.

This is used for flat-layout execution such as:

python -m cli

where relative imports fail, and where some filenames (like io.py) would otherwise collide with Python stdlib modules.

Parameters:
  • module_name (str)

  • filename (str)

Return type:

ModuleType

transmissions.shift_schedule_builder

transmissions.shift_schedule_builder.infer_rich_mode_from_payload(payload)[source]
Parameters:

payload (Mapping[str, Any])

Return type:

bool

transmissions.shift_schedule_builder.parse_shift_schedule_csv(text, *, rich=False, allow_header=True)[source]

Parse a CSV-ish shift schedule editor.

Legacy/simple examples

1st, A, B, C 2nd, A, B, E Rev, A, B, D

Rich examples

state, active_constraints, display_elements, manual_neutral, notes N, C3|B1, C3|B1, true, Neutral state 1st, C3|B1|B2|F1|F2, C3|B1|B2|F1|F2, false,

Separator rules

  • CSV separates columns

  • Within active/display columns, elements may be split by | ; + or whitespace

Parameters:
  • text (str)

  • rich (bool)

  • allow_header (bool)

Return type:

dict[str, Any]

transmissions.shift_schedule_builder.save_shift_schedule_payload(payload, path)[source]
Parameters:
  • payload (Mapping[str, Any])

  • path (str | Path)

Return type:

Path

transmissions.shift_schedule_builder.schedule_payload_to_csv(payload, *, rich=None)[source]
Parameters:
  • payload (Mapping[str, Any])

  • rich (bool | None)

Return type:

str

transmissions.transmission_spec_builder

transmissions.transmission_spec_builder.build_spec_payload(*, name, input_member, output_member, strict_geometry, members_text='', speed_display_order_text='', speed_display_labels_text='', gearsets_text='', clutches_text='', brakes_text='', sprags_text='', permanent_ties_text='', display_order_text='', state_aliases_text='', presets_text='', notes='', meta_text='')[source]
Parameters:
  • name (str)

  • input_member (str)

  • output_member (str)

  • strict_geometry (bool)

  • members_text (str)

  • speed_display_order_text (str)

  • speed_display_labels_text (str)

  • gearsets_text (str)

  • clutches_text (str)

  • brakes_text (str)

  • sprags_text (str)

  • permanent_ties_text (str)

  • display_order_text (str)

  • state_aliases_text (str)

  • presets_text (str)

  • notes (str)

  • meta_text (str)

Return type:

dict[str, Any]

transmissions.transmission_spec_builder.save_spec_payload(payload, path)[source]
Parameters:
  • payload (Mapping[str, Any])

  • path (str | Path)

Return type:

Path

transmissions.transmission_spec_builder.spec_payload_to_editors(payload)[source]
Parameters:

payload (Mapping[str, Any])

Return type:

dict[str, str]

transmissions.gui_utils_trans

class transmissions.gui_utils_trans.TaskResult(ok: 'bool', value: 'Any', error: 'str' = '')[source]

Bases: object

Parameters:
  • ok (bool)

  • value (Any)

  • error (str)

error: str = ''
ok: bool
value: Any
transmissions.gui_utils_trans.ensure_dir(p)[source]
Parameters:

p (str | Path)

Return type:

Path

transmissions.gui_utils_trans.extract_dpg_file_dialog_path(app_data)[source]
Parameters:

app_data (Any)

Return type:

str

transmissions.gui_utils_trans.find_repo_root(start=None)[source]

Best-effort repo root discovery.

Supports either: - flat-layout project with app.py/model.py at root - package layout with transmissions/__init__.py

Parameters:

start (str | Path | None)

Return type:

Path

transmissions.gui_utils_trans.in_dir(repo_root)[source]
Parameters:

repo_root (Path)

Return type:

Path

transmissions.gui_utils_trans.list_json_files(root)[source]
Parameters:

root (Path)

Return type:

list[Path]

transmissions.gui_utils_trans.list_schedule_files(root)[source]
Parameters:

root (Path)

Return type:

list[Path]

transmissions.gui_utils_trans.list_spec_files(root)[source]
Parameters:

root (Path)

Return type:

list[Path]

transmissions.gui_utils_trans.load_json(path)[source]
Parameters:

path (str | Path)

Return type:

dict[str, Any]

transmissions.gui_utils_trans.load_text(path)[source]
Parameters:

path (str | Path)

Return type:

str

transmissions.gui_utils_trans.nonempty_lines(text)[source]
Parameters:

text (str)

Return type:

list[str]

transmissions.gui_utils_trans.open_path(path)[source]
Parameters:

path (str | PathLike[str] | Path)

Return type:

bool

transmissions.gui_utils_trans.out_dir(repo_root)[source]
Parameters:

repo_root (Path)

Return type:

Path

transmissions.gui_utils_trans.parse_bool(text, default=False)[source]
Parameters:
  • text (Any)

  • default (bool)

Return type:

bool

transmissions.gui_utils_trans.parse_csv_lines(text)[source]
Parameters:

text (str)

Return type:

list[list[str]]

transmissions.gui_utils_trans.parse_name_list(text)[source]
Parameters:

text (str)

Return type:

list[str]

transmissions.gui_utils_trans.pretty_json(payload)[source]
Parameters:

payload (Any)

Return type:

str

transmissions.gui_utils_trans.run_task_async(fn, *, on_done=None)[source]
Parameters:
  • fn (Callable[[], Any])

  • on_done (Callable[[TaskResult], None] | None)

Return type:

Thread

transmissions.gui_utils_trans.save_json(path, payload, *, indent=2)[source]
Parameters:
  • path (str | Path)

  • payload (Mapping[str, Any])

  • indent (int)

Return type:

None

transmissions.gui_utils_trans.save_text(path, text)[source]
Parameters:
  • path (str | Path)

  • text (str)

Return type:

None

transmissions.gui_utils_trans.unique_path(base)[source]
Parameters:

base (Path)

Return type:

Path

transmissions.gui_log_trans

class transmissions.gui_log_trans.DpgLogHandler(panel, *, level=20)[source]

Bases: Handler

Parameters:
emit(record)[source]

Do whatever it takes to actually log the specified logging record.

This version is intended to be implemented by subclasses and so raises a NotImplementedError.

Parameters:

record (LogRecord)

Return type:

None

class transmissions.gui_log_trans.LogPanel(tag_level: 'str' = '##trans_log_level', tag_box: 'str' = '##trans_log_box', tag_status: 'str' = '##trans_log_status', tag_clear_btn: 'str' = '##trans_log_clear', default_level: 'str' = 'INFO', max_chars: 'int' = 250000)[source]

Bases: object

Parameters:
  • tag_level (str)

  • tag_box (str)

  • tag_status (str)

  • tag_clear_btn (str)

  • default_level (str)

  • max_chars (int)

build(parent=None, *, height=240, mono_font=None)[source]
Parameters:
  • parent (object | None)

  • height (int)

  • mono_font (int | None)

Return type:

None

clear()[source]
Return type:

None

debug(msg)[source]
Parameters:

msg (str)

Return type:

None

default_level: str = 'INFO'
drain(*, max_lines=200)[source]
Parameters:

max_lines (int)

Return type:

None

error(msg)[source]
Parameters:

msg (str)

Return type:

None

info(msg)[source]
Parameters:

msg (str)

Return type:

None

max_chars: int = 250000
set_status(msg)[source]
Parameters:

msg (str)

Return type:

None

tag_box: str = '##trans_log_box'
tag_clear_btn: str = '##trans_log_clear'
tag_level: str = '##trans_log_level'
tag_status: str = '##trans_log_status'
warn(msg)[source]
Parameters:

msg (str)

Return type:

None

transmissions.gui_core_trans

class transmissions.gui_core_trans.AppState(repo_root: 'Path', in_root: 'Path', out_root: 'Path', ui_font_default: 'int | None' = None, ui_font_macos: 'int | None' = None, ui_font_labview: 'int | None' = None, mono_font: 'int | None' = None, log_handler: 'logging.Handler | None' = None, last_spec_path: 'str' = '', last_schedule_path: 'str' = '', last_output_json: 'str' = '', history: 'list[str] | None' = None)[source]

Bases: object

Parameters:
  • repo_root (Path)

  • in_root (Path)

  • out_root (Path)

  • ui_font_default (int | None)

  • ui_font_macos (int | None)

  • ui_font_labview (int | None)

  • mono_font (int | None)

  • log_handler (Handler | None)

  • last_spec_path (str)

  • last_schedule_path (str)

  • last_output_json (str)

  • history (list[str] | None)

history: list[str] | None = None
in_root: Path
last_output_json: str = ''
last_schedule_path: str = ''
last_spec_path: str = ''
log_handler: Handler | None = None
mono_font: int | None = None
out_root: Path
repo_root: Path
ui_font_default: int | None = None
ui_font_labview: int | None = None
ui_font_macos: int | None = None
class transmissions.gui_core_trans.ThemeSpec(label: 'str', key: 'str', theme_id: 'int', dialog_theme_id: 'int | None', font_id: 'int | None')[source]

Bases: object

Parameters:
  • label (str)

  • key (str)

  • theme_id (int)

  • dialog_theme_id (int | None)

  • font_id (int | None)

dialog_theme_id: int | None
font_id: int | None
key: str
label: str
theme_id: int
transmissions.gui_core_trans.drain_tasks(q, *, max_tasks=50)[source]
Parameters:
  • q (SimpleQueue[Callable[[], None]])

  • max_tasks (int)

Return type:

None

transmissions.gui_core_trans.enqueue_task(q, fn)[source]
Parameters:
  • q (SimpleQueue[Callable[[], None]])

  • fn (Callable[[], None])

Return type:

None

transmissions.gui_core_trans.main()[source]
Return type:

int

transmissions.gui_core_trans.t(prefix, name)[source]
Parameters:
  • prefix (str)

  • name (str)

Return type:

str