Observatory Dependency Decoupling


If you have any queries regarding the stated project ask them here


The Project is a bit hard since we don’t have hardware access to check it upon, and yeah stimulators are a good yet inefficient option, But I thought that YOU or someone would be having an access of that sort of stuff, won’t you?


actually my mid terms are going on right now,so I was a bit busy, but i will compensate for the time that I lose:sweat_smile:


The simulators are actually a very time efficient alternative to the real hardware because we can control the passage of time; for example, let’s say it normally takes 10 to 20 seconds for the mount to move into the parked position (cameras facing straight down at the ground, on the East side of the mount, assuming it is in the northern hemisphere). In the simulator we make that take any amount of time that we like, from too long (allowing us to test timeout conditions) to instantaneous (allowing us to move through a series of tests very quickly).


I have no idea about any sort of stimulator that i can use? Can you recommend me something to read about? @james.synge


and what exactly is scheduler injection? A bit more insight of the project would be helpful


Hi @harsh-not-haarsh, thanks for jumping in! The general idea with decoupling is to make our main class (the Observatory) more flexible to the types of hardware and scheduler that it can use. Currently the Observatory instance itself will create the various hardware pieces, e.g. it will call something like self._create_mount() and self._create_scheduler(). You can see these in the init method for the Observatory.

However, this becomes a problem when we want different types of devices. Currently this is handled via config files, so that self._create_mount() will read config files and build the object as appropriate. This leads to some ugly code, for instance see the actual _create_mount method.

Instead what we want is to have some other process create the mount and scheduler and pass those as complete objects to the Obsevatory. This is already done with the cameras, which is why the Observatory takes that as a param.

You can read more on DI here or the wikipedia article.

So really the DI as a first step is nothing more than setting up a system to create the objects outside of the Observatory and then passing them to the Observatory upon creation.


The simulators that we have are custom-built so part of POCS. You can, for instance:

from pocs.core import POCS
from pocs.observatory import Observatory

obs = Observatory(simulators=['all'])
pocs = POCS(obs, messaging=True)

And that gets you a system that is up and working. Things like pocs.observatory.get_target() will then query the simulator. It’s helpful to look at the log files (in /var/panoptes/POCS by default).


And to be clear, a simulator in this context just means a piece of software (e.g. a Python class) that has the same interface as a driver used for interacting with a piece of equipment (or even an external software package), but that doesn’t actually control anything. Some simulators can even be used for testing the hardware drivers. For example, the Astrohaven Dome Simulator acts as a serial device, providing responses that simulates those that the PLC (Programmable Logic Controller) supplied with the dome provides.

We currently have the following simple simulators (i.e. ones that don’t emulate a particular piece of hardware, and simply replace a driver):

  1. Camera
  2. Dome
  3. Filter Wheel
  4. Focuser
  5. Mount

There are also implicit simulators for “night” (if this one is enabled, then it is always night), and for “weather” (if enabled, then the weather is always good).

And we have these simulators that imitate the communication of a real device:

  1. Astrohaven Dome
  2. Arduino; this emulates the timing and sensor value reporting of our Arduino programs, which is useful for validating that the drivers are working correctly.

A simulator I’ve been interested in writing is for the iOptron mount, the primary one we use in the PANOPTES design. The command language (a serial protocol) is documented here. Our driver for that mount is here; that driver also uses this table for mapping abstract commands to strings to be sent and parsed.