Grand tour dashboard¶
Requires the viz extra for the widgets and the mdao/smt extras for
the sizing and verdict strips (pip install "longeron[viz,mdao,smt]").
The grand-tour dashboard: every analysis seam on one linked surface.
One grand_dashboard() call composes the house widgets over a drone
model (plus the multi-mission sizing model) into a single reactive
dashboard – the capability finale of the tutorial series (tutorial 9):
a structure diagram pane (
longeron.diagrams.structure_diagram(), compact toolbar on) – the linked-selection hub;a 3D CAD pane (
longeron.widgets.viewer3d.mesh_viewer()), config-keyed throughlongeron.analysis.link.bind_config_view()(tutorial 7’s seam, promoted): clicking ANY craft in the diagram – a build configuration, a fleet airframe shell, or the mission catalog’s variant usages – renders THAT craft in the pane, while selections inside the shown craft highlight per M0 individual; a translucent view cone follows the camera what-if sliders over the home assembly;a requirements scoreboard pane (
longeron.analysis.scoreboard.scoreboard(), Voronoi tessellation) scoring the model’s own requirement hierarchy, repainted live as the measured geometry changes;a camera what-if card – elevation/azimuth sliders that re-run the CAD-native occlusion measure (
longeron.analysis.geometry. occlusion_report(), deterministic mesh engine) on every move;an OpenMDAO sizing strip – the sizing part’s generated
Problem(longeron.analysis.mdao.build_problem()), re-run live from a loiter-speed slider, with a one-click driver run that snaps the slider to the optimum;a Z3 verdict strip – requirement-consistency cards (
longeron.analysis.smt.to_smt()): the design point’s SAT witness beside an impossible what-if’s UNSAT conflict core;a Cesium mission pane (
longeron.widgets.mission3d) flying the drone’s own geometry through its recorded state-machine execution over satellite imagery (offline front-ends degrade to a printed note; the dashboard composes regardless).
WIRING MAP – everything reacts to everything, kernel-side, through traitlets observers (so the whole surface works headless):
diagram click -> 3D highlight (and mesh pick -> diagram selection);
diagram click on another craft -> the 3D pane bakes and shows THAT craft (the camera what-if keeps measuring the home assembly);
diagram click on a requirement -> scoreboard selection (and a scoreboard cell click -> diagram selection);
camera sliders -> occlusion re-measure -> the view cone repaints, the obstructing parts highlight in 3D, the occlusion readout lists them, the scoreboard recolors, and the header score updates;
loiter slider ->
run_model-> the sizing cards repaint; the maximize button runs the optimization driver and snaps the slider.
Requires the viz extra for the widgets and the mdao/smt
extras for the sizing and verdict strips:
pip install "longeron[viz,mdao,smt]".
- longeron.analysis.grand.ATLANTA_LOOP: tuple[tuple[float, float, float], ...] = ((33.7813, -84.3833, 350.0), (33.7885, -84.3785, 390.0), (33.79, -84.3695, 380.0), (33.7838, -84.369, 360.0), (33.777, -84.3825, 350.0))¶
default mission route: a small loop over Piedmont Park, midtown Atlanta –
(lat, lon, alt m MSL); the ground there sits ~300 m MSL
- longeron.analysis.grand.FLIGHT_EVENTS: tuple[Any, ...] = (2.0, 'launch', 6.0, 'airborne', 150.0, 'low_battery', 10.0)¶
default event feed for the flight state machine replay (the
Interpreter.simulateprotocol: numbers advance the clock)
- longeron.analysis.grand.drone_scene(model, assembly='Rotorcraft::QuadCopter')[source]¶
Bake the tagged per-instance mesh for a drone-family assembly.
Interprets
assemblyat M0 (longeron.m0.interpret()), sizes the parametric mesh from the population’s own attribute values (longeron.analysis.geometry.drone_geometry(),split_instances=True), and stamps every rendered part with its M0 individual id (tutorial 7’s identity keys). The rotor population picks the frame family – the CONFIG-KEYED rendering seam: amotorspopulation fans out one arm per member (the quad and the hexa),frontMotors+tailMotorbuild the three-arm tricopter with its tail boom, andupperMotors+lowerMotorsstack the coaxial pairs (uppers takemotor1..4/ the first propeller individuals, lowers follow). The assembly must have the MultiRotor build-family shape of the DeepScout program (examples/deepscout):chassis,battery, andpropellersslots, one of the rotor-population shapes above, plus an optionalcamerawhose placement/boresight attributes drive the occlusion checks. Pair withlongeron.analysis.link.owning_config()to resolve a diagram selection anywhere inside a configuration to the configuration this function renders. Returns(mesh, part_map).
- longeron.analysis.grand.grand_dashboard(model, sizing=None, *, assembly='Rotorcraft::QuadCopter', states='DeepScout::FlightStates', sizer='ScoutSizing::IsrPrime', station_requirement='ScoutSizing::IsrStation', station_var='stationMinutes', loiter_var='loiterSpeed', what_if_station=420.0, values=None, waypoints=((33.7813, -84.3833, 350.0), (33.7885, -84.3785, 390.0), (33.79, -84.3695, 380.0), (33.7838, -84.369, 360.0), (33.777, -84.3825, 350.0)), events=(2.0, 'launch', 6.0, 'airborne', 150.0, 'low_battery', 10.0), ground_alt=300.0, imagery='satellite')[source]¶
The grand-tour dashboard (an ipywidgets
VBox) – one call.modelcarries the drone: its structure feeds the diagram, its interpreted M0 population sizes the 3D mesh, its requirement hierarchy is the scoreboard, and itsstatesmachine flies the Cesium mission overwaypoints.sizing(default:modelitself) carries the continuous side:sizerbecomes the OpenMDAO problem behind the loiter slider, andstation_requirementthe Z3 consistency cards – the what-if card demandsstation_var >= what_if_stationwithloiter_varfreed, an impossible floor whose UNSAT core names the binding constraints.valuesinjects extra measured scoreboard bindings (e.g. performance measures computed through the interpreter); the live occlusion and disc-overlap measures are merged on top.See the module docstring for the pane list and the wiring map. The returned layout exposes every piece for scripting and tests:
.diagram,.viewer,.board(+.scoreboard, the currentScoreboard),.elevation/.azimuth/.readout/.report,.loiter/.optimize/.problem/.optimum,.smt_sat/.smt_what_if,.mission/.track,.mesh/.part_map/.camera,.header,.config_view(theConfigViewBindingbehind the config-keyed 3D pane), and.unlink(drops the diagram <-> 3D binding).- Return type:
- longeron.analysis.grand.scene_for(model, config, *, interpreter=None, tilt_deg=None)[source]¶
Bake the tagged scene for ANY renderable craft definition.
One dispatcher over both DeepScout craft families. A fleet airframe shell – a definition whose own attributes evaluate to the
Airframegeometry knobs (wingSpan,wingArea,taper,fuselageLength,motorCount,armCount) – renders throughlongeron.analysis.geometry.airframe_geometry()at nominal display propulsion. Every part carries the definition’s qualified name as its identity key (selecting the def lights the whole craft), EXCEPT the clickable internals: a renderedbattery,fc, orcamerapart whose shell declares the matching part usage (battery/flightController/camera– every DeepScout fleet shell does) carries THAT usage’s qualified name, so picking the battery in the scene selects the battery element, not just the craft. Anything else goes todrone_scene(): the MultiRotor build family bakes from its own M0 population with per-individual identity keys, and non-assembly shapes fail loudly withAnalysisError.This is the config-keyed rendering seam behind
longeron.analysis.link.bind_config_view(): resolve a selection to its owning configuration, hand the configuration here, swap the viewer to the result.tilt_degis the tilt-rotor family’s conversion state (hover 90 .. cruise 0, the scene-level knob behindtilt_viewer()); shells that declare no pivot chain ignore it. Returns(mesh, part_map).
- longeron.analysis.grand.tilt_viewer(model, config='TiltRotors::TiltTriWing', *, tilt_deg=90.0, width_px=640, height_px=420)[source]¶
A mesh viewer with the tilt-rotor conversion affordance.
One
longeron.widgets.viewer3d.mesh_viewer()over oneipywidgetsslider: the slider commands the conversion state, sweeping hover (90 deg) to cruise (0), and every move re-bakes the scene throughscene_for()at that tilt – the tip pods and the nose unit rotate about the pivots the MODEL declares, so the slider drives the same geometry the interference gate samples. The returnedVBoxexposes the pieces for scripting and tests:.viewer(the mesh viewer),.tilt(the slider), and.part_map. Requires thevizextra.- Return type:
- longeron.analysis.grand.view_cone_part(camera, *, length, name='viewCone', segments=48, color='#7a5d8c', opacity=0.25)[source]¶
A translucent view-cone mesh part for the 3D scene.
Apex at the camera position, axis along the azimuth/elevation boresight, half-angle
fieldOfView / 2, reachinglengthmetres – the same constructionlongeron.analysis.geometry. occlusion_report()measures, here as a display part (append it to a scene’sparts; never to the analysis mesh, where it would count as an obstruction).camerauses the attribute names of the DeepScout program’sScoutParts::F450Kit::Camerapart. Untagged, so linked selection ignores it.