| // ***************************************************************************** |
| // 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} |
| */ |
| } |