blob: 01dac8d08bf36010fb31c1f29028da8cc0f05a62 [file] [log] [blame]
// *****************************************************************************
// Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// Pierre Allard - initial API and implementation
//
// SPDX-License-Identifier: EPL-1.0
// *****************************************************************************
@GenModel(prefix="ApogyExamplesLander",
copyrightText="*******************************************************************************
Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Pierre Allard - initial API and implementation
SPDX-License-Identifier: EPL-1.0
*******************************************************************************",
modelName="ApogyExamplesLander",
childCreationExtenders="true",
extensibleProviderFactory="true",
suppressGenModelAnnotations="false",
dynamicTemplates="true",
templateDirectory="platform:/plugin/org.eclipse.apogy.common.emf.codegen/templates")
@GenModel(modelDirectory="/org.eclipse.apogy.examples.lander/src-gen")
@GenModel(editDirectory="/org.eclipse.apogy.examples.lander.edit/src-gen")
package org.eclipse.apogy.examples.lander
import org.eclipse.apogy.common.emf.Disposable
import org.eclipse.apogy.addons.vehicle.Thruster
import org.eclipse.apogy.common.Apogy
// Types
/**
* A 3x3 Matrix, used to help implement the lander's position,
* namely the 3D pose of the lander.
*/
type Matrix3d wraps javax.vecmath.Matrix3d
/*
* Apogy Example Lander Facade.
*/
@Apogy(isSingleton="true", hasCustomClass="true")
class ApogyExampleLanderFacade{
/**
* Returns a new Lander object, which has the same type as
* the given lander.
*
* @param lander The lander with a particular implementation.
* @return The new lander, which has the same type as the other one
*/
op Lander makeLanderSameType(Lander lander)
}
/**
* This class defines the position of an object in 3D space.
* In particular, it provides the object's Cartesian coordinates
* (x, y, z) as a 3x3 matrix corresponding to its current rotation
* in all three axes.
*/
@Apogy(hasCustomClass="true", hasCustomItemProvider="true")
class Position
{
/**
* This is an object's X position in 3D space
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Location")
@Apogy(units="m")
double x
/**
* This is an object's Y position in 3D space
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Location")
@Apogy(units="m")
double y
/**
* This is an object's Z position in 3D space
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Location")
@Apogy(units="m")
double z
/**
* This is a 3x3 matrix, representing an object's rotations
* (if any) in all three of the primary axes.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Attitude")
Matrix3d attitude
}
/**
* This enumeration is used to define the possible levels
* of extension that the lander's legs can have.
*/
enum LanderLegExtension
{
/**
* This defines a lander leg position in which the
* leg is not extended at all.
*/
LegPosition1 as "Position 1" = 0,
/**
* This defines a lander leg position in which the
* leg is extended a third of a full possible extension.
*/
LegPosition2 as "Position 2" = 100,
/**
* This defines a lander leg position in which the
* leg is extended two-thirds of a full possible extension.
*/
LegPosition3 as "Position 3" = 200,
/**
* This defines a lander leg position in which the
* leg is completely extended.
*/
LegPosition4 as "Position 4" = 300
}
/**
* This abstract class represents a four-legged lander,
* including all of its relevant state information (e.g.
* position, current leg extensions, etc.) as well as
* the operations that it can perform.
*/
@Apogy(hasCustomClass="true", hasCustomItemProvider="true")
abstract class Lander extends Disposable
{
/**
* This represents the lander's position in 3D space,
* both in terms of Cartesian coordinates as well
* as the current 3D orientation of lander (represented
* as rotations from the primary axes)
*/
@GenModel(notify="true",
propertyCategory="Position")
contains Position[1] position
/**
* This represents the lander's thruster, which controls
* the flight.
*/
@GenModel(notify="true",
propertyCategory="Flight")
contains Thruster thruster
// ------------------------------------------------------------
// Note: There is an important distinction between
// the leg*Extension and leg*Position sets of
// variables; the leg*Extension variables refer
// to <b>desired</b> extension level for the
// lander's legs while the leg*Position variables
// refer to the <b>current</b> extension position
// of the legs.
// <p>
// While, in general, the two should be the same
// for the majority of the time, the difference
// shows up when leg*Extension is changed; this
// will mean that the leg*Position is out of sync
// with the new leg*Extension. In order to
// compensate, the leg will likely need to
// physically actuate in order to change the leg's
// current extension position, leg*Position; as
// this is not an instantaneous process, there will
// a probably be a period of time where the leg*Position
// is not at any of the well-known positions in
// LanderLegPosition while the leg is moving to reflect
// the new leg*Extension level.
//
// As such, leg*Extension and leg*Position are closely
// related but differ in some circumstances.
// -------------------------------------------------------------------
/**
* This represents the desired / selected level of
* extension for the lander's leg A.
*/
@GenModel(children="false",
notify="true",
propertyCategory="Leg Extension Levels")
LanderLegExtension legAExtension
/**
* This represents the desired / selected level of
* extension for the lander's leg B.
*/
@GenModel(children="false",
notify="true",
propertyCategory="Leg Extension Levels")
LanderLegExtension legBExtension
/**
* This represents the desired / selected level of
* extension for the lander's leg C.
*/
@GenModel(children="false",
notify="true",
propertyCategory="Leg Extension Levels")
LanderLegExtension legCExtension
/**
* This represents the current extension position
* for the lander's leg A.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Leg Positions")
@Apogy(units="m")
double legAPosition = "0"
/**
* This represents the current extension position
* for the lander's leg B.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Leg Positions")
@Apogy(units="m")
double legBPosition = "0"
/**
* This represents the current extension position
* for the lander's leg C.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Leg Positions")
@Apogy(units="m")
double legCPosition = "0"
/**
* This represents the current angular velocity
* (in radians per second) of the lander in the X
* direction.
* <p>
* Note: Unlike the traditional definition of angular
* velocity as a vector, this is simply a signed scalar;
* a positive value is the rotation in the counter-
* clockwise direction while a negative value implies the
* rotation is in the clockwise direction. Zero means
* there is no rotation.
* @see #commandAngularVelocities(double, double)
*/
@GenModel(children="false",
notify="true",
propertyCategory="Velocities")
@Apogy(units="rad/s")
double xAngularVelocity = "0"
/**
* This represents the current angular velocity
* (in radians per second) of the lander in the Y
* direction.
* <p>
* Note: Unlike the traditional definition of angular
* velocity as a vector, this is simply a signed scalar;
* a positive value is the rotation in the counter-
* clockwise direction while a negative value implies the
* rotation is in the clockwise direction. Zero means
* there is no rotation.
* @see #commandAngularVelocities(double, double)
*/
@GenModel(children="false",
notify="true",
propertyCategory="Velocities")
@Apogy(units="rad/s")
double yAngularVelocity = "0"
/**
* This represents the mass of the lander (in kg).
*/
@GenModel(children="false",
property="Readonly",
propertyCategory="Flight")
@Apogy(units="rad/s")
transient volatile readonly derived double mass
/**
* This represents the fuel mass of the lander (in kg).
*/
@GenModel(children="false",
property="Readonly",
propertyCategory="Flight")
@Apogy(units="kg")
transient double fuelMass
/**
* This is the amount of force (in N) of gravity that is being
* imposed upon the lander.
* <p>
* Recall that that the gravitational force impose on an object
* (like a lander) in relation to a celestial body is affected by:
* <ul>
* <li>the mass of the lander</li>
* <li>the mass of the celestial body the lander is on / above</li>
* <li>the distance between the lander and the body</li>
* </ul>
* @return The amount of gravitational force (in N) imposed upon the lander
*/
@GenModel(children="false",
property="Readonly",
propertyCategory="Flight")
@Apogy(units="N")
transient volatile readonly derived double gravitationalPull
/**
* This represents whether or not the lander's legs are
* currently extending / retracting, as a result of a
* commandLegPosition() operation; initially false.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Status")
boolean changingLegs = "false"
/**
* This represents whether or not the lander is currently
* changing its attitude, as a result of a changeAttitude() /
* resetAttitude() operation; initially false.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Status")
boolean changingAttitude = "false"
/**
* This represents whether or not the lander is currently
* changing its coordinate location, as a result of a moveTo()
* operation; initially false.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Status", propertyDescription="")
boolean changingLocation = "false"
/**
* This represents whether the lander is currently permitted
* to fly. Just note that this does not necessary mean that
* the lander will actually fly; that's dependent on a number
* of factors.
* @see #startFlying()
* @see #stopFlying()
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Flight")
boolean flyingEnabled = "false"
/**
* This represents whether or not the lander has been
* successfully initialized; initially false.
* @see #init()
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Status")
boolean initialized = "false"
/**
* This represents whether or not the lander has been
* successfully disposed; initially false.
*/
@GenModel(children="false",
notify="true",
property="Readonly",
propertyCategory="Status")
boolean disposed = "false"
/**
* This operation performs the steps required in order to
* initialize the lander.
* @return Whether or not the lander was successfully initialized
*/
op boolean init()
/**
* This operation is used to change the extension positions
* for each of the legs of the lander. Note that extending or
* retracting the legs is a non-instantaneous process and it's
* likely it will take some period of time to move the lander's
* legs to the target positions.
* @param legAExtension The new leg extension position for leg A.
* @param legBExtension The new leg extension position for leg B.
* @param legCExtension The new leg extension position for leg C.
*/
op void commandLegPosition(LanderLegExtension legAExtension,
LanderLegExtension legBExtension,
LanderLegExtension legCExtension)
/**
* This operation is used to move the lander to the specified X, Y and
* Z coordinates.
* @param x The lander's new desired X coordinate
* @param y The lander's new desired Y coordinate
* @param z The lander's new desired Z coordinate
*/
op void moveTo(double x, double y, double z)
/**
* This operation is used to change the lander's attitude /
* orientation to the specified angles.
* @param xAngle The lander's new angle of rotation (in radians) around the X axis
* @param yAngle The lander's new angle of rotation (in radians) around the Y axis
* @param zAngle The lander's new angle of rotation (in radians) around the Z axis
*/
op void changeAttitude(@Apogy(units="rad") double xAngle,
@Apogy(units="rad") double yAngle,
@Apogy(units="rad") double zAngle)
/**
* This operation is used to reset the lander's attitude /
* position to its initial state, namely where there is no
* rotation from any of the primary axes (X, Y, Z).
*/
op void resetAttitude()
/**
* This operation is used to update the both the lander's
* X and Y angular velocities (in radians per second.)
* <p>
* Note 1: These velocities are only used while the lander
* is flying; while not flying, changing these values
* will have no effect.
* <p>
* Note 2: Unlike the traditional definition of angular velocity
* as a vector, this is simply a signed scalar; a positive
* value is the rotation in the counter-clockwise direction
* while a negative value implies the rotation is in the
* clockwise direction. Zero means there is no rotation.
* @param xAngularVelocity The new X angular velocity for the lander (given in radians / second)
* @param yAngularVelocity The new Y angular velocity for the lander (given in radians / second)
*/
op void commandAngularVelocities(@Apogy(units="rad/s") double xAngularVelocity,
@Apogy(units="rad/s") double yAngularVelocity)
/**
* This operation is used to update the lander's thrust level
* (which is given in newtons.)
* <p>
* Note: The thrust level is always bounded by
* [thruster.getMinimumThrust(), thruster.getMaximumThrust()]
*
* @param thrustLevel The lander's new thrust level (given in N)
*/
op void commandThrust(@Apogy(units="N") double thrustLevel)
/**
* This operation is used to change the lander's current thrust
* level by the specified (absolute) offset (which is given in
* newtons.)
* <p>
* Note: The thrust level is always bounded by
* [thruster.getMinimumThrust(), thruster.getMaximumThrust()]
*
* @param thrustOffset The amount (in N) that the thrust level should be increased / decreased.
*/
op void changeThrustBy(@Apogy(units="N") double thrustOffset)
/**
* This operation is used to permit the lander to start flying.
* <p>
* Whether or not the lander is able to actually fly is dependent on
* the mass of the lander, the lander's current thrust and the gravity
* being used (e.g. the Earth's gravity, g ~= -9.81); there may
* potentially be other factors as well.
* @param logStateChanges Whether or not to log the state changes that occur because it has started flying
* @see #canFly()
* @see #stopFlying()
*/
op void startFlying(boolean logStateChanges)
/**
* This operation is used to indicate that the lander is no longer
* allowed to fly and should stop doing so; it may need to perform
* actions to land the lander.
* @see #canFly()
* @see #startFlying(boolean)
*/
op void stopFlying()
}
/**
* This is a specific implementation of the lander, in which all
* operations are stubs and hence, non-functional; the methods
* should simply output a message indicating that they were performed.
*/
@Apogy(hasCustomClass="true", hasCustomItemProvider="true")
class LanderStub extends Lander
{
/**
* For specific implementation details,
* see {@link org.eclipse.apogy.examples.lander.impl.LanderStub}
*/
}
/**
* This is a specific implementation of the lander, in which all
* operations are simulated; while there is no physical components
* interacted with, it attempts to emulate, wherever possible, the
* actions and results of its real world counterpart.
*/
@Apogy(hasCustomClass="true", hasCustomItemProvider="true")
class LanderSimulated extends Lander
{
/**
* For specific implementation details,
* see {@link org.eclipse.apogy.examples.lander.impl.LanderSimulated}
*/
}