Grounds

This application models a ground stations at the Svalbard Satellite Station location with minimum elevation angle constraints.

The application contains one class, the Environment class, which waits for a message from the manager that indicates the beginning of the simulation execution. The application publishes the ground station information once, at the beginning of the simulation.


Class

class Environment(app, grounds)

Bases: Observer

The Environment object class inherits properties from the Observer object class in the NOS-T tools library

app

An application containing a test-run namespace, a name and description for the app, client credentials, and simulation timing instructions

Type:

ManagedApplication

grounds

DataFrame of ground station information including groundId (int), latitude-longitude location (GeographicPosition), min_elevation (float) angle constraints, and operational status (bool)

Type:

DataFrame

Environment.on_change(source, property_name, old_value, new_value)

Standard on_change callback function format inherited from Observer object class

In this instance, the callback function checks when the PROPERTY_MODE switches to EXECUTING to send a GroundLocation message to the PREFIX/ground/location topic:

        if (
            property_name == Simulator.PROPERTY_MODE
            and new_value == Mode.EXECUTING
            and old_value != Mode.RESUMING
        ):
            logger.info("Grounds are operational")
            for index, ground in self.grounds.iterrows():
                self.app.send_message(
                    self.app.app_name,
                    "location",
                    GroundLocation(
                        groundId=ground.groundId,
                        latitude=ground.latitude,
                        longitude=ground.longitude,
                        elevAngle=ground.elevAngle,
                        operational=ground.operational,
                    ).model_dump_json(),
                )

Schema

Schema are implemented using the pydantic library. The following schema define consistent message structures between this application and other observer applications:

pydantic settings GroundLocation

Bases: BaseModel

Message schema object class with properties inherited from the pydantic library’s BaseModel

Standardized message for ground station information includes:

Show JSON schema
{
   "title": "GroundLocation",
   "description": "*Message schema object class with properties inherited from the pydantic library's BaseModel*\n\nStandardized message for ground station information includes:",
   "type": "object",
   "properties": {
      "groundId": {
         "description": "Unique ground station identifier.",
         "title": "Groundid",
         "type": "integer"
      },
      "latitude": {
         "description": "Latitude (deg) of ground station.",
         "maximum": 90,
         "minimum": -90,
         "title": "Latitude",
         "type": "number"
      },
      "longitude": {
         "description": "Longitude (deg) of ground station.",
         "maximum": 180,
         "minimum": -180,
         "title": "Longitude",
         "type": "number"
      },
      "elevAngle": {
         "description": "Minimum elevation angle (deg) for satellite-ground communications",
         "title": "Elevangle",
         "type": "number"
      },
      "operational": {
         "default": true,
         "description": "True, if this ground station is operational.",
         "title": "Operational",
         "type": "boolean"
      }
   },
   "required": [
      "groundId",
      "latitude",
      "longitude",
      "elevAngle"
   ]
}

Fields:
  • groundId (int)

  • latitude (float)

  • longitude (float)

  • elevAngle (float)

  • operational (bool)

field groundId: int [Required]

Unique ground station identifier.

field latitude: float [Required]

Latitude (deg) of ground station.

Constraints:
  • ge = -90

  • le = 90

field longitude: float [Required]

Longitude (deg) of ground station.

Constraints:
  • ge = -180

  • le = 180

field elevAngle: float [Required]

Minimum elevation angle (deg) for satellite-ground communications

field operational: bool = True

True, if this ground station is operational.


Startup Script

The following code demonstrates how the ground application is started up and how the Environment Observer object class is initialized and added to the simulator:

    # Define application name
    NAME = "ground"

    # Load config
    config = ConnectionConfig(yaml_file="firesat.yaml", app_name=NAME)

    # Create the managed application
    app = ManagedApplication(app_name=NAME)

    # Get the ground station information from the configuration
    stations = config.rc.application_configuration["stations"]
    GROUND = pd.json_normalize(stations)[
        [
            "groundId",
            "latitude",
            "longitude",
            "elevAngle",
            "operational",
        ]
    ]

    # Add the environment observer to monitor simulation for switch to EXECUTING mode
    app.simulator.add_observer(Environment(app, GROUND))

    # Add a shutdown observer to shut down after a single test case
    app.simulator.add_observer(ShutDownObserver(app))

    # Add the daily time scale updater observer
    app.simulator.add_observer(DailyFreeze(app, freeze_duration=timedelta(minutes=1)))

    # Start up the application
    app.start_up(
        config.rc.simulation_configuration.execution_parameters.general.prefix,
        config,
    )

    while True:
        pass