seeing-things / track

Automates tracking of targets with a telescope using ephemeris (TLE files) and/or optical tracking.
MIT License
7 stars 0 forks source link

Add non-interactive mode for `align_guidescope` #261

Closed bgottula closed 1 year ago

bgottula commented 1 year ago

The align_guidescope program currently requires some user interaction to confirm that it's doing the right thing, but this prevents more complete automation.

bgottula commented 1 year ago

I realized that the current approach may require some inter-process communication for synchronization to make the script fully automated. The bright star is held at the center of the main camera by means of a subprocess which performs a spiral search followed by bringing the star to the center of the camera once it is found. While that subprocess continues running to hold the star at camera center, a still image is taken with the guidescope camera for plate solving. The user provides the synchronization event by answering a prompt when the star is centered in the main camera preview window. Without user interaction, the subprocess will need to somehow inform the parent process that the star is centered, which will indicate to the parent script that it's time to proceed.

I think the logic to detect when the star is centered already exists, but normally that logic is used to terminate the controller. In this case we don't want the controller to stop; we instead want it to inform another process that this condition has been satisfied.

One approach would be to use multiprocessing which allows for synchronization primitives like multiprocessing.Event to be shared between processes. For this to work, I think __main__.py would need to be refactored such that there is a function handle that can be passed to multiprocessing.Process with configuration passed in by function arguments rather than command line arguments.

bgottula commented 1 year ago

I attempted to implement the multiprocessing approach but ran into a number of challenges:

The more I use it the more disenchanted I become with multiprocessing. It seems like it's built on a bunch of fragile hacks that only work for trivial use cases. All I need is for one process to send a one-way signal to another process. Maybe I'd be better off reverting to subprocess.run . I can achieve the desired inter-process communication by passing the child process the PID of the parent process so it can just send a signal like SIGUSR1. The parent can wait for that signal with signal.sigtimedwait(). Not the most elegant, but compared with multiprocessing's hideous warts it might look rather attractive.

bgottula commented 1 year ago

I just realized that the approach I'm using in the control module to determine if the mount is converged on the target only checks if the separation angle between the mount position and the target position is small, but this isn't the right criterion.

bgottula commented 1 year ago

Problem: How to specify how close to center of frame is close enough.

What should determine this:

What units should be used for the threshold:

How:

bgottula commented 1 year ago

The problem I'm dealing with now is that the program arguments I'm adding to track's main() function are very specific to CameraTarget and do not work for any other target. So when I add a program argument specifying the separation angle below which SIGUSR1 should be sent I have to write an awkward and lengthy help message that points out how it only applies under very limited circumstances and so on.

I realized that I should just move these program arguments into the target module under the camera subparser, and furthermore the code that actually sends the signal can then just be moved into the CameraTarget class eliminating the need for any callbacks from main(). That seems like it ought to be much cleaner and avoids cluttering up main() with these concerns.

bgottula commented 1 year ago

After sleeping on it, I've changed my mind about the previous comment. I'd rather main() be responsible for unusual side effects like sending signals to other processes, even if it clutters up main() a bit, such that none of the Target objects including CameraTarget need to be directly involved in inter-process communication concerns.

This is the best I can think of for now. It's not super pretty, but it will get the job done and I think the coupling introduced is as minimal as it can be while solving the problem.

bgottula commented 1 year ago

The basics have been implemented, but still need to be tested outside since I don't have a way to do a full integrated test of align_guidescope indoors.

Thinking through some checks that could be automated: