Obtaining RA/Dec coordinates directly after plate solve only

Discussions on extending SharpCap using the built in Python scripting functionality
Post Reply
rl_kabi
Posts: 7
Joined: Fri Jul 28, 2023 10:41 pm

Obtaining RA/Dec coordinates directly after plate solve only

#1

Post by rl_kabi »

Hi there!

Is it possible to obtain the direct values for the RA/Dec coordinates resulting from a plate solve (no sync)?

I know that when the task is completed, the GUI shows the results about if the plate solve was successful and where it is pointing. However, I'd like to be able to access that in my code directly as opposed to having to look at the coordinates myself. Ideally this could allow me to use the coordinates' values in other things, such as syncing my mount to those coordinates, slewing to another point close by in the sky, et cetera.

Cheers,

RL
User avatar
admin
Site Admin
Posts: 13362
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Obtaining RA/Dec coordinates directly after plate solve only

#2

Post by admin »

Hi,

yes, that should be possible - try this

Code: Select all

from SharpCap.Interfaces import PlateSolvePurpose
from System.Threading import CancellationToken
print (SharpCap.BlindSolver.SolveAsync(PlateSolvePurpose.Annotation, CancellationToken() ).Result)
Note that normally you would use CancellationToken.None to specify no cancellation token, but 'None' is a reserved keyword in python, so you have to work around it and just create a CancellationToken that will never be cancelled.

cheers,

Robin
rl_kabi
Posts: 7
Joined: Fri Jul 28, 2023 10:41 pm

Re: Obtaining RA/Dec coordinates directly after plate solve only

#3

Post by rl_kabi »

Hi Robin,

I tried that code snippet directly and it seems it doesn't work - I got an AttributeError saying that " 'PlateSolveOnly' object has no attribute 'SolveAsync' ", so what I did was just changing that part to Solve like below:

Code: Select all

SharpCap.BlindSolver.Solve(PlateSolvePurpose.MountSync, CancellationToken()).Result
(I changed Annotation to MountSync instead because my goal is to work out where the telescope is pointing ... unless Annotation will allow for that better, maybe my understanding isn't quite right?)

However, it still didn't work like that and SharpCap seemed to freeze somehow, rendering me unable to click on any options on the toolbar. The notification/status bar popped up at the top saying "Capturing a frame to plate solve..." like normal but after that, there were some more logs pertaining to CaptureSingleFrame before it stopped logging things. Not sure why, so in case that is of interest, I've attached the log. The relevant lines are near the very end starting at 10:19.

I have kind of found a way to make it work by assigning the solving task to a variable/object, then calling .Result on that object to obtain the RA/Dec Coordinates. However, that only worked well in the console, which I think is because it ensured the plate solving task was complete before trying to access the results. With a script calling it, it didn't work. I tried making the call synchronous with Wait() but for some reason SharpCap froze again and the log stopped at the same place as before. Below is what I had in my script when trying to test this way of obtaining the coordinates. I've also attached the (much smaller) log for this chunk of code.
Screenshot 2023-08-31 122503.png
Screenshot 2023-08-31 122503.png (58.23 KiB) Viewed 6465 times

Code: Select all

from System.Threading import CancellationToken
from SharpCap.Interfaces import PlateSolvePurpose

TestCam1Solve = SharpCap.BlindSolver.Solve(PlateSolvePurpose.MountSync, CancellationToken())
TestCam1Solve.Wait()
# ends up not working

print(TestCam1Solve.Result) 
print(TestCam1Solve.Result.RightAscension)
print(TestCam1Solve.Result.Declination)
Any idea as to why this is happening?

Cheers,
RL
Attachments
Log_2023-08-31T11_06_44-15116.log
(44.81 KiB) Downloaded 85 times
Log_2023-08-31T10_03_16-27484.log
(344.89 KiB) Downloaded 93 times
User avatar
admin
Site Admin
Posts: 13362
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Obtaining RA/Dec coordinates directly after plate solve only

#4

Post by admin »

Ouch...

just spent the last hour or so looking into this and it's not nice :(

First the easy bit - I was testing with SharpCap 4.1, and the name of the function is 'SolveAsync' in 4.1 to make it clearer that it is an asynchronous call. In 4.0 it was just 'Solve'.

The hard bit is working out how to properly wait for the asynchronous operation to complete without locking up the script running thread and with it the actual asynchronous operation. The problem is that the scripting has to run in a thread set up to run UI components, otherwise people couldn't use scripting to add their own forms, windows, buttons, etc to SharpCap. But in a UI thread, it's not safe to use .Wait() or .Result on a task (for anyone who really cares about why, read this : https://devblogs.microsoft.com/pfxteam/ ... cks-oh-my/).

Right now the (ugly) workaround I have come up with is as follows

Code: Select all

clr.AddReference("System.Windows.Forms")
from time import sleep
from SharpCap.Interfaces import PlateSolvePurpose
from System.Threading import CancellationToken
from System.Windows.Forms import Application
from System.Threading.Tasks import TaskStatus
task = SharpCap.BlindSolver.SolveAsync(PlateSolvePurpose.Annotation, CancellationToken() )
while (task.Status < TaskStatus.RanToCompletion):
	sleep(0.1)
	Application.DoEvents()
print (task.Result)
This waits for the task to finish in a loop, and periodically processes windows events, which bypasses the deadlock. If you are running on 4.0 then change SolveAsync to Solve, but the same fix should apply.

I will see if I can make a helper function available for this in the next update.

cheers,

Robin
User avatar
admin
Site Admin
Posts: 13362
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Obtaining RA/Dec coordinates directly after plate solve only

#5

Post by admin »

OK, I have a cleaner helper function now for the next SharpCap 4.1 update - the code becomes

Code: Select all

from SharpCap.Interfaces import PlateSolvePurpose
from System.Threading import CancellationToken

task = SharpCap.BlindSolver.SolveAsync(PlateSolvePurpose.Annotation, CancellationToken() )
result = SharpCap.SafeGetAsyncResult(task)
print (result)
There is no real need for the task and result variables to be assigned and then used - the whole lot can be collapsed to a single line.

If you do not wish to get the result, just want to wait until it has finished then

SharpCap.SafeWaitForAsync(task)

cheers,

Robin
Post Reply