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:
ObserverThe 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
GroundLocationmessage 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:
BaseModelMessage 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