Robots and wings¶
flapsim.robot.loader
¶
Load a robot from a manifest, a bare URDF/MJCF file, or an MjSpec.
RobotModel
dataclass
¶
A compiled MuJoCo model with its manifest and wing objects.
geometry_warnings()
¶
Frame and joint-sign warnings for every wing at the current pose.
load(source, *, manifest=None, base=None, position=None, timestep=None, scene=True, check=True)
¶
Build a :class:RobotModel.
source is a built-in robot name, a manifest file, a bare URDF/MJCF
file, a :class:RobotManifest, or an :class:mujoco.MjSpec (then pass
its manifest separately or get a wing-less default). base
overrides the manifest's base type ("fixed" or "free"),
position the spawn position and timestep the integrator step.
With check the wing frames and joint signs are sanity-checked at the
neutral pose and problems are reported as warnings.
resolve_manifest(source)
¶
Accept a manifest, a manifest path, a model path or a built-in name.
builtin_robots()
cached
¶
Map every built-in robot name and alias to its manifest file.
flapsim.robot.manifest
¶
Robot manifest: what a URDF or MJCF file cannot say about a flapping robot.
A manifest is a small YAML or JSON document that lives next to the model file.
It names the torso and the wings, gives each wing its aerodynamic frame, its
stroke and feathering joints and its planform, and lists the model patches
(joint dynamics, equality constraints, mass overrides) that MuJoCo needs but
URDF cannot express. :meth:RobotManifest.from_file parses and validates it
and :func:flapsim.robot.load turns it into a compiled MuJoCo model with
:class:~flapsim.wings.Wing objects attached.
Conventions¶
- Vectors are expressed in the frame of the body they belong to.
frame.spanpoints from the wing root to the tip along the feathering axis;frame.chordpoints from the leading edge (the hinge line) to the trailing edge. FlapSim derives the surface normal from them, so the side of the hinge on which the wing lies is never ambiguous.signon a joint reference converts the MuJoCo joint coordinate into the aerodynamic convention:psi = sign * qpos.whenon a patch restricts it to"fixed"or"free"base models; the default"always"applies it to both.
RobotManifest
dataclass
¶
ModelSpec
dataclass
¶
BaseSpec
dataclass
¶
ModelPatches
dataclass
¶
JointPatch
dataclass
¶
Joint properties URDF cannot express (all SI, None leaves MuJoCo's).
BodyPatch
dataclass
¶
Mass-property overrides for one body (or "*" for all others).
EqualityPatch
dataclass
¶
An equality constraint between two joints or two bodies.
WingSpec
dataclass
¶
WingFrame
dataclass
¶
Aerodynamic frame of a wing in its body frame, or the name of a site.
span points from root to tip along the feathering axis and chord
from the leading edge (hinge line) to the trailing edge. For a site,
the site's +X is the chord direction and +Y the span direction.
WingMass
dataclass
¶
Mass properties of a wing body, given in wing coordinates.
Wing coordinates are (normal, span, chord) with span positive from
root to tip and chord positive from the leading to the trailing edge, so
mirrored wings share the same numbers.
type: thin_plate: a uniform plate coveringlength x mean_chord.type: spar_plate: a leading-edge spar (rod along the span) holdingspar_fractionof the mass plus a uniform membrane plate holding the rest. This is the usual mass distribution of a membrane wing and the one that gives physically correct passive feathering.type: explicit:comanddiaginertiaabout the wing axes through the centre of mass.
Planform
dataclass
¶
Wing planform: how to obtain the blade-element integrals.
profile selects the source: an analytic shape (rectangular or
elliptic, needs length and mean_chord), a chord polyline
of (r, c) pairs in metres from root to tip, or explicit integrals.
pitch_axis_fraction is the chordwise position of the feathering axis
measured from the leading edge as a fraction of the chord (hinge inside
the plate); leading_edge_offset is the distance in metres from the
feathering axis to the leading edge when the plate starts beyond the
hinge (a root spar). Use one or the other.
JointRef
dataclass
¶
TorsoSpec
dataclass
¶
ManifestError
¶
Bases: ValueError
Raised when a robot manifest is malformed or contradicts itself.
flapsim.robot.builders
¶
Parametric robots built in Python, for users without CAD and for tests.
flat_plate_flapper(*, span=0.07, chord=0.02, thickness=0.0005, shoulder=0.012, body_mass=0.03, wing_mass=0.0001, arm_mass=0.0002, stroke_range=1.5, feathering_range=0.785398, feathering_stiffness=2e-07, feathering_damping=1e-09, feathering_armature=1e-10, spar_fraction=0.8, timestep=5e-05, position=(0.0, 0.0, 0.5), name='flat_plate_flapper')
¶
A two-wing flapper with rectangular flat-plate wings.
The torso sits at the origin and the wings span the body x axis. At
the neutral pose each plate is vertical: its normal points along -y
(the stroke direction) and its chord hangs down (-z) from the
leading-edge hinge. This is the quasi-steady model's convention, in which
a feathering angle of zero means the plate meets the stroke flow at 90
degrees. The stroke joints rotate about +z (left) and -z (right),
so equal joint angles give mirrored motion; the passive feathering joints
rotate about +x for both wings. Returns the MjSpec and a matching
manifest; pass both to :func:flapsim.robot.load. The wing mass is
distributed as a leading-edge spar (spar_fraction) plus a membrane
plate through the manifest's mass model.
flat_plate_simulation(*, frequency_hz=30.0, amplitude_rad=1.2, base='fixed', aero='aero/quasi_steady', **builder_kwargs)
¶
A :class:~flapsim.core.Simulation of :func:flat_plate_flapper.
The stroke joints are driven sinusoidally (equal angles give mirrored
motion) and the quasi-steady aero plugin is attached unless aero is
None.
flapsim.robot.inspect
¶
Describe a compiled MuJoCo model so a user can write a manifest quickly.
flapsim.wings.wing
¶
Runtime wing: a manifest :class:WingSpec resolved against a MuJoCo model.
The aerodynamic frame of a wing has +X along the surface normal, +Y
along the feathering axis and +Z = X x Y; the chord extends from the
hinge along -Z. From the manifest's span (root to tip) and chord
(leading to trailing edge) vectors: Y = side * span, Z = -chord and
X = Y x Z. Mirrored wings therefore share one frame orientation at the
neutral pose (for a right wing +Y is the negative root-to-tip direction)
and the side factor in the aerodynamic formulas puts the centre of
pressure back on the wing. This is the convention of the quasi-steady model
in :mod:flapsim.fluid.aero.
WingState
dataclass
¶
Kinematic state of one wing read from MjData.
Wing
¶
body_mass_properties()
¶
(mass, com_body, fullinertia_body) from the manifest mass model.
Wing coordinates (normal, span, chord) map onto the aero axes as
(X, side * Y, -Z); the inertia is rotated into the body frame and
returned as [Ixx, Iyy, Izz, Ixy, Ixz, Iyz].
geometry_warnings(model, data)
¶
Plain-language warnings when the frame or joint signs look reversed.
Checks, at the current (neutral) pose: the wing's centre of mass lies
on the chord side of the hinge (-Z), a positive stroke rate moves
the wing against +X (so the relative flow is along +X), and a
positive feathering rate rotates the wing about +Y.
apply_wrench(data, force_world, torque_world)
¶
Write a world-frame wrench about the body centre of mass.
flapsim.wings.planform
¶
Wing planform integrals for blade-element aerodynamics.
The quasi-steady model needs chord-weighted radial moments of the planform.
With the non-dimensional span coordinate r_hat = r / R and chord
c_hat = c(r) / c_mean they are
r_kk = integral c_hat * r_hat**kfor k = 0..3 (normal force),z_cpk = integral c_hat**2 * r_hat**kfor k = 0..2 (pitching moment),z_rd = integral (|y_te| y_te**3 - |y_le| y_le**3) / c_mean**4(rotational damping), whereyis the chordwise distance from the feathering axis to the trailing and leading edges.
For a rectangular wing hinged at its leading edge all of them are
1 / (k + 1) and z_rd = 1. Several constructors are offered: analytic
profiles, a chord polyline, a planform polygon and a mesh outline.
from_chord_distribution(r_hat, c_hat, *, pitch_axis_fraction=0.0, samples=20001)
¶
Integrals of a sampled chord distribution c(r_hat) on [0, 1].
c_hat may carry any unit; it is normalised to a unit mean chord. The
points define a piecewise-linear chord, which is resampled on samples
points before trapezoid integration so that coarse polylines integrate
accurately.
from_profile(profile, *, pitch_axis_fraction=0.0, samples=20001)
¶
Integrals of an analytic planform: rectangular or elliptic.
from_polyline(points, *, pitch_axis_fraction=0.0)
¶
Integrals of a chord polyline [(r, c), ...] in metres, root to tip.
Returns (length, mean_chord, integrals).
from_polygon(polygon, hinge_origin, span_direction, chord_direction, *, quadrature_order=24, axis_tolerance=0.01)
¶
Integrals of a planar planform polygon given in metres.
polygon is an (N, 2) outline in any planar coordinates,
hinge_origin the wing root on the feathering axis, span_direction
the axis towards the tip and chord_direction the axis from the leading
edge towards the trailing edge. The quasi-steady moment formula assumes
the feathering axis runs along the leading edge; pitch_axis_exact in
the result reports whether the outline satisfies that within
axis_tolerance.
read_stl_triangles(path)
¶
Return the triangles of a binary or ASCII STL file as (N, 3, 3).
read_stl_vertices(path)
¶
Return the unique vertices of a binary or ASCII STL file as (N, 3).
from_mesh(path, *, span_axis, chord_axis, hinge_origin=(0.0, 0.0, 0.0), bins=64, scale=1.0, samples_per_edge=64)
¶
Approximate planform integrals from a wing mesh (STL).
Vertices are projected onto the span_axis/chord_axis plane and
binned along the span; each bin's chord is the extent of its vertices in
the chord direction. chord_axis points from the leading edge towards
the trailing edge and hinge_origin lies on the feathering axis.
scale converts the mesh unit to metres (1e-3 for millimetre
meshes). The result is an approximation whose quality depends on the
mesh resolution and on bins.
resolve_planform(planform)
¶
Turn a manifest :class:~flapsim.robot.manifest.Planform into numbers.
wing_params(length, mean_chord, integrals, *, rho=1.225, d0=0.0, ds=0.0, x_le=0.0, x0=0.0)
¶
Assemble the flat parameter object used by the quasi-steady model.