# Implementation Docs ## Required functionality - Achieve target angles for tilt values (target is 0) - Achieve target values for lateral velocity (when no thrust is being applied, 0) - Achieve target values for for/aft velocity when thrust is applied - When direction indicators are referenced and autopilot is on, keep all direction indicator values beside "fore" at 0 - A monitor that displays the following values: - Directional thrust values (0-15 & 0-100%) - Rotational thrust values (0-15 & 0-100%) - Velocity values - Altitude values - Navigation target values (if applicable) - Autopilot controls ## Create: Avionics relevant Peripheral methods When Create: Avionics is installed, all sensors get direct peripherals for CC:T Relevant peripherals: - Velocity Sensor - Navigation Table - Gimbal Sensor - Altitude Sensor - Analog Transmission ### Altitude Sensor implementations > Peripheral ID: altitude_sensor - `getHeight()`: get the sensor's Y coordinate - `getAirPressure()`: get the local air pressure at the sensor's altitude - `getVerticalSpeed()`: get the sensor's vertical speed (positive is ascending, negative is descending) ### Navigation Table implementations > Peripheral ID: navigation_table - `hasTarget()`: Check whether the table has resolved a target - `getTargetType()`: returns a string target type ID, or nil if no item is held - `getTargetMetadata()`: returns per-type metadata for the target. > Metadata schema: > > - `simulated:compass`: `kind` ("lodestone"|"spawn"), `sublevel_id` (string, lodestone only) > - `sublevel_id` is the tracker UUID > - `simulated:recovery_compass`: `placer_uuid` (string, optional) > - `placer_uuid` is absent until a player has placed the compass into the table > - `simulated:map`: `map_id` (number, optional) > - `map_id` is absent if the held map carries no MAP_ID data component (e.g. a blank map) > - `simulated:magnet`: --- > - static target (10 blocks north of the table) - `getRelativeAngle()`: get the relative angle to the target, in degrees - `getRelativeAngleRad()`: get the relative angle to the target, in radians - `getBearing()`: get the forward-error bearing to the target, in degrees - Forward-error bearing: - 0 -> target is straight ahead of the blocks arrow (direct fore) - +90 -> target is to the right (direct starboard) - -90 -> target is to the left (direct port) - +-180 -> target is directly behind (direct aft) - `getBearingRad()`: get the forward-error bearing to the target, in randians - `getDistanceToTarget()`: get the distance to the resolved target - `getClosureRate()`: gets the rate at which the table is closing on the target in blocks/sec (positive is approaching, negative is leaving) - `getVerticalOffsetToTarget()`: gets the vertical offset between the target and the table (the difference of `target.y - self.y`) - `getOrientation()`: gets the host sub-level's orientation as a quaternion {x, y, z, w} > Matches JOML's constructor and the convention used by CC quaternion libraries (e.g. TechTastic/Advanced-Math) - `getHeading()`: Gets the host sub-level's heading in degrees > 0 degrees refers to world +Z, minecraft south - `getHeadingRad()`: gets the host sub-level's heading in radians ### Gimbal Sensor > Peripheral ID: gimbal_sensor - `getAngles()`: get the contraption's pitch and roll angles in degrees - xAngle: rotation about body-X (pitch). 0 degrees is aligned with world-up - zAngle: rotation about body-Z (roll). 0 degrees is aligned with world-up - returns {xAngle, zAngle} - `getAnglesRad()`: get the contraption's pitch and roll angles in radians - `getAngularRates()`: get the contraption's angular velocity in degrees/sec - wx: pitch rate - wy: yaw rate - wz: roll rate - returns {wx, wy, wz} - `getAngularRatesRad()`: get the contraption's angular velocity in radians/sec - `getGravity()`: gets the local gravity vector in body frame, in m/s^2 - returns {gx, gy, gz} - `getLinearAcceleration()`: get the contraption's proper acceleration in body frame, in m/s^2 - returns {ax, ay, az} ### Velocity Sensor > Peripheral ID: velocity_sensor - `getVelocity()`: gets the velocity component along the sensor's axis - returns signed velocity in m/s > note: returns 0 if the magnitude is below 0.05 m/s - `getAxis()`: returns the body-frame axis the sensor measures along - returns string "x", "y", and "z" ### Analog Transmission > Peripheral ID: analog_transmission > > These are used as controllers for rotationally-powered thruster blocks - `getSignal()`: get the current signal driving the transmission ratio - returns an integer between 0 and 15 - `setSignal(signal)`: set the signal driving the transmission ratio > Note: flips externallyControlled, even when signal == current > > The documented way to get control without changing the value is calling `setSignal(getSignal())`. - `releaseSignal()`: Release external control and return signal driving to redstone - `isExternallyControlled()`: Check whether the transmission is currently under script control - `getRotationModifier()`: get the current rotation modifier (output:input speed ratio) - `getOutputSpeed()`: get the output shaft speed - `getOutputTheoreticalSpeed()`: get the output shaft's theoretical (target) speed - `getOutputStressImpact()`: get the output-side stress impact (post-ratio kinetic accounting) - `isOversaturated()`: check whether the transmission is oversaturated - `getAxis()`: get the transmission's shaft axis name - returns the axis as string "x", "y", or "z" - `getSelfId()`: get this block's ID > Note: other peripherals' getSourceId or getSubnetworkAnchorId will return this ID when they refer to this block - `getSourceId()`: get the ID of the block immediately driving this one, or nil if theis block has no source - `getSubnetworkAnchorId()`: get the ID of this block's speed-zone anchor -- the gearshift/clutch/speed controller/generator that defines the start of this speed zone. > Note: Two blocks share an anchor if they're in the same speed zone. A generator or split-shaft returns its own `getSelfId()` - `getNetworkId()`: get the ID of this block's kinetic network. - `getKind()`: returns one of "generator", "split_shaft", "consumer", or "passthrough" - `getSpeed()`: get the local rotational speed at this block. - `hasSource()`: check whether this block is connected to a kinetic source - `isOverstressed()`: check whether this block's network is overstressed - `getStressImpact()`: get the stress impact of this block on its network. zero for sources and pure conduit blocks - `getStressContribution()`: get this block's contribution to its network's stress capacity. Non-zero for sources only ## Peripheral Notes - Analog Transmissions signal speed changes: - 0: no change from input speed - 14: maximum change from input speed - 15: input and output rotational networks are decoupled (generally means no output rotation) - All that is to say, when being driven properly, the minimum speed is at signal 15, and increasing the speed goes from the lowest nonzero RPM at signal 0 to the highest at signal 14. ## Implementation On startup, call these methods: - All Analog Transmission's `getSelfId()` - All rotationally controlled thruster's `getSubnetworkAnchorId()` If the ID returned by a thruster's `getSubnetworkAnchorId()` is also returned by an analog transmission's `getSelfId()`, associated that transmission with the thruster Also upon startup, check for a configuration file with other thruster's peripherals, or redstone-controlled thrusters Every cycle: - Check for new machines in the network. If new machines are found, initialize them similarly to the startup - Gimbal Sensor `getAngles()`, `getAngularRates()`, and `getLinearAcceleration()` - Navigation Table `getHeading()`, `hasTarget()`, and depending on the output of `hasTarget()`: - if true, call `getBearing()`, `getDistanceToTarget()`, `getClosureRate()`, and `getVerticalOffsetToTarget()` - if false, continue to the next sensors - Altitude Sensor `getHeight()`, `getAirPressure()`, `getVerticalSpeed()` - Velocity Sensor `getAxis()`, `getVelocity` - Poll input signal strengths for global downwards thrust, and fore and aft thrust