pub fn rocket(document: &Document) -> Imported<Rocket>Expand description
Reads a design document into a Rocket: its stages, the body components stacked in them, and
the parts on and inside each of those.
Never fails: a tag it cannot read is left out with a Warning, so a design written by another
program still opens. The result is a Rocket whose body components are in file order, forward
to aft, with automatic dimensions marked rather than filled in: Rocket::layout resolves
them, and is where a part’s mass and station come from.
A body tube or inner tube that holds a motor is marked as a motor mount, but the motors
themselves are not read here, and Rocket::configurations is left empty:
super::design reads them. A <motormount> it cannot read still warns here.
let xml = br#"<?xml version="1.0" encoding="UTF-8"?>
<openrocket version="1.10" creator="OpenRocket 24.12">
<rocket><name>Sounder</name><subcomponents><stage><name>Sustainer</name><id>s</id>
<subcomponents>
<nosecone><name>Nose</name><id>nose</id><finish>smooth</finish>
<material type="bulk" density="680.0">Cardboard</material>
<length>0.3</length><thickness>0.002</thickness>
<shape>ogive</shape><shapeparameter>1.0</shapeparameter>
<aftradius>0.05</aftradius></nosecone>
<bodytube><name>Tube</name><id>tube</id>
<material type="bulk" density="680.0">Cardboard</material>
<length>0.6</length><thickness>0.002</thickness><radius>0.05</radius>
<subcomponents>
<centeringring><name>Ring</name><id>ring</id>
<material type="bulk" density="680.0">Plywood</material>
<axialoffset method="bottom">0.0</axialoffset><length>0.005</length>
<outerradius>auto</outerradius><innerradius>0.019</innerradius></centeringring>
</subcomponents></bodytube>
</subcomponents></stage></subcomponents></rocket>
</openrocket>"#;
let read = hpr_io::ork::read(xml)?;
let design = hpr_io::ork::rocket(&read.value.document);
// Anything the reader could not take at face value travels with the result. Nothing here did.
assert!(design.warnings.is_empty(), "{:?}", design.warnings);
// The ring's outer radius says `auto`, so the design carries the dimension, not a number...
use hpr_design::AutoDimension;
let ring = &design.value.stages[0].components[1].children[0];
assert!(ring.auto.contains(&AutoDimension::OuterRadius));
// ...and the layout works it out: the bore of the tube the ring sits in, 0.05 - 0.002.
let layout = design.value.layout()?;
let (_, placed) = layout.find("ring").expect("the ring");
let hpr_design::Part::CenteringRing(ring) = &placed.part else { panic!("a ring") };
assert!((ring.outer_radius_m - 0.048).abs() < 1e-12);
assert!(placed.own.mass_kg > 0.0);