Jump to content

  •  

CNers have asked about a donation box for Cloudy Nights over the years, so here you go. Donation is not required by any means, so please enjoy your stay.

Photo

FOSS Observatory Automation

  • Please log in to reply
20 replies to this topic

#1 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 23 February 2024 - 03:03 PM

Hey all:

 

I posted this on my SubStack but I thought I'd share it here too. FOSS=Free, Open Source software. Comments welcome!

 

KStars has been around since 2001. With the addition of the Ekos telescope control, imaging, solving, focus and guiding module, it has become a very core application for astrophotography on Linux, Macintosh and Windows platforms, with very close ties to the INDI standard for interfacing with astronomy equipment. INDI will only run on UNIX-derived operating systems like Linux and Macintosh. However, the Mac version of INDI does not have an easy-to-install distribution, having essentially forked into INDIGO on Linux and MacOS. KStars and Ekos are also embedded in ASI products like the ASIAir and SeeStar, with more vendors like Celestron probably hopping on board to use Open Source to control their equipment for autoscopes like the forthcoming Celestron Origin line of telescopes.
 

kstars.jpg

 

It’s easy to write clients to control INDI equipment in Python - there’s a library available named PyINDI for that purpose. For example, I currently open and close my observatory (while I revamp my INDI-compatible controller) with Python scripts using PyIndi to park the telescope before moving the roof so it doesn’t strike it.

 

My ambitions are more significant than that- I would like to write code to control all aspects of the observatory based on weather conditions. So, I would like to do the following via Python:

  •     Determine if weather conditions are suitable for opening the roof (see my Detecting Clouds and Arduino Rain Detector articles for more info)
  •     Open the Roof of the Micro-Observatory
  •     Ensure KStars is running and invoke an Ekos Schedule
  •     Shut down the schedule if the weather turns bad
  •     Park the telescope and close the roof
  •     Wrap it all up in a web based management software system that allows me to pick targets and tell the observatory how to observe them e.g. astroimage (take subs, calibrate, stack, and   send me the result), varstar (image a varstar, calculate it's magnitude), exoplanet (take a sequence of images, calc the magnitude in each, give me a graph) etc.

This work can be done from Python using PyIndi or by directly controlling KStars and EKOS via D-Bus. D-Bus was developed as part of the freedesktop.org project, initiated by GNOME developer Havoc Pennington to standardize services provided by Linux desktop environments such as GNOME and KDE.

 

It’s easy to see how D-Bus works using the qdbus command line tool. To see what services (paths) are offered by KStars, use qdbus from the command line

$ qdbus org.kde.kstars

To ask KStars to do something, send the appropriate service a message with your request. For example to position the pointer on the KStars main screen you could use this command:

$ qdbus org.kde.kstars /KStars org.kde.kstars.lookTowards "M 33"

So org.kde.kstars is the service name, /KStars is the path, and org.kde.kstars.lookTowards is the method that is being invoked. To see what methods are provided by the Scheduler, you can use:

$ qdbus org.kde.kstars /KStars/Ekos/Scheduler

Here’s the result:

property read QStringList org.kde.kstars.Ekos.Scheduler.logText
property readwrite QString org.kde.kstars.Ekos.Scheduler.profile
property read int org.kde.kstars.Ekos.Scheduler.status
signal void org.kde.kstars.Ekos.Scheduler.newLog(QString text)
signal void org.kde.kstars.Ekos.Scheduler.newStatus({D-Bus type "(i)"} status)
method bool org.kde.kstars.Ekos.Scheduler.loadScheduler(QString fileURL)
method Q_NOREPLY void org.kde.kstars.Ekos.Scheduler.removeAllJobs()
method Q_NOREPLY void org.kde.kstars.Ekos.Scheduler.resetAllJobs()
method Q_NOREPLY void org.kde.kstars.Ekos.Scheduler.setSequence(QString sequenceFileURL)
method Q_NOREPLY void org.kde.kstars.Ekos.Scheduler.start()
method Q_NOREPLY void org.kde.kstars.Ekos.Scheduler.stop()
signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface_name, QVariantMap changed_properties, QStringList invalidated_properties)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
method QString org.freedesktop.DBus.Peer.GetMachineId()
method void org.freedesktop.DBus.Peer.Ping()

So now we have the tools we need to check if Ekos is running, load a Scheduler, and Start and Stop it. First, Let’s take a closer look at the Ekos Scheduler. Below, the main Scheduler screen is running with a sample schedule to image M31.  To create the test file we will load through DBUS, I manually entered M31 as my target and selected a Sequence (created by the Imaging module and saved as test.esq), which specified camera, exposure, gain, offset, filter, etc.  and saved it as test.esl.

 

scheduler.jpg

 

Next, I ensure that Track, Focus, Align, and Guide are checked. When this schedule is executed, the Scheduler will first slew the telescope to where it thinks M31 is and then do a plate solve to determine if the galaxy is indeed in the centre of the field of view. If not, it iterates and refines the position until the object is centred. The Focus module is run next to do an autofocus to ensure the object is in perfect focus. Finally, the Guide module is engaged to start auto-guiding, using the internal guide or PHD2 (“Push Here Dummy 2”), an excellent Open Source guiding tool.  Ekos communicates with PHD2 via DBUS, so they are connected seamlessly. And, of course, if you need to do anything connected to auto-guiding in your Python program, PHD2 can be accessed similarly.

 

To run a schedule in Ekos first we need to connect to the bus and create a couple of objects for Ekos and the Scheduler. We’re using PyDBus to make it easy to access DBus.

from pydbus import SessionBus
import time
# Create a DBUS object
bus = SessionBus()# Connect to the Ekos and Ekos Scheduler objects
try:
    ekos=bus.get("org.kde.kstars","/KStars/Ekos")
    ekosScheduler=bus.get("org.kde.kstars","/KStars/Ekos/Scheduler")
except:
    print("Unable to accesss KStars, please load it.")
    exit(-1)

Next, we need to start up Ekos and load a profile. In this case, we load the built-in simulator profile that has everything we need to test.

# Start up Ekos, and load the Simulators profile
ekos.start()
if 'Simulators' in ekos.getProfiles():
    ekos.setProfile('Simulators')
else:
    print('Error: Simulators profile not present')

Now lets load a Schedule, run it, and print out what the log says. We’ll sleep for 30s to let it run for a bit.

# Load a schedule and start it running
ekosScheduler.loadScheduler('/home/gtulloch/Projects/EKOSProcessingScripts/test.esl')
ekosScheduler.start()
print('Scheduler status is',ekosScheduler.status)
print(ekosScheduler.logText)
time.sleep(30)

The log looks like below, so we can detect keywords and check that everything is working ok if need be:

['2024-02-21T14:22:21 Scheduler started.', '2024-02-21T14:22:21 Scheduler is awake.']

Finally, let’s say we detect rain and need to shut everything down.

# Oh no it's raining! Stop the scheduler and close Ekos
ekosScheduler.stop()
print(ekosScheduler.logText)
ekos.stop()

So that’s all we need!  I'll stop for any feedback before moving on to the Master Control Program.


Edited by gordtulloch, 23 February 2024 - 03:29 PM.

  • lambermo, R Botero, Andreas_Roerig and 5 others like this

#2 peculiar_polar_ring

peculiar_polar_ring

    Vostok 1

  • -----
  • Posts: 144
  • Joined: 14 Nov 2017

Posted 23 February 2024 - 09:52 PM

I love this, thank you for this journey. I'm all in on NINA because it's wonderful and I've contributed, even though it runs in a non FOSS OS.

I hope with stellarmate and asi air Linux drivers will get more love by manufacturers. Too many don't have an official indi driver

#3 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 24 February 2024 - 12:55 PM

I love this, thank you for this journey. I'm all in on NINA because it's wonderful and I've contributed, even though it runs in a non FOSS OS.

I hope with stellarmate and asi air Linux drivers will get more love by manufacturers. Too many don't have an official indi driver

Thanks! Honestly, it hasn't been a problem for me, I just pick stuff that already has INDI drivers rather than picking the hardware and then looking for drivers. I think a lot of angst around INDI and Stellarmate is "It doesn't work with my <not terribly common device>". Nope, it doesn't.  And a couple of Windows versions from now, it won't work with Windows either >:)



#4 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 24 February 2024 - 01:06 PM

obs.jpg

 

In the last post, I reviewed our tools for automating KStars and Ekos, which provide a complete suite of tools for operating a telescope and taking pictures. Using D-Bus, we can control these programs as if we’re at the keyboard, allowing us to take advantage of these programs' capabilities rather than reinvent the wheel.  Now we can tie all the disparate parts together into a Master Control Program to run the observatory in a completely autonomous way.

 

Each component needs to be working before we get to this point clearly - if the telescope isn’t focusing with auto-focus, trying to run Ekos schedules that include auto-focusing is kind of pointless!

 

To do this, I implemented a service on our Linux-based telescope controller (in my case, running the Stellarmate X OS on a Beelink MiniPC) that uses a Python program that continuously loops, checking weather, opening and closing the roof and invoking an Ekos scheduler. 

 

I’ve simplified and removed comments, logging, etc., from the code. As the program evolves, you can see it here in my Github repo for EKOS Processing Scripts

 

After we set up D-Bus and KStars/Ekos as in the previous articles. The main loop essentially implements 4 states for the observatory: Closed, Close Pending (we’re open, but some clouds are rolling in), Open Pending (it’s clearing up!) and Open (execute the daily Ekos Schedule), and calls Python functions to detect weather and daytime, open and close, run schedules, etc.

while True:
     # If needed shut down and wait 5 mins
     if getRain() or checkSun():
          ekosScheduler.stop()
          obsyState = "Closed"
          obsyClose()
          time.sleep(300)
          continue
     # Stay closed or move to Close Pending if Open
     if mlCloudDetect() or getWeather():
          if obsyState == "Closed":
               time.sleep(60)
               continue
          # If Open give it PENDING minutes to change
          if obsyState == "Open":
              obsyState="Close Pending"
              pendingCount=1
              if obsyState == "Close Pending":
                 pendingCount+=1
              if pendingCount == maxPending:
                 obsyState="Closed"
                 obsyClose()  
                 pendingCount=0
     else:   
          # Good weather so set to Open Pending or Open
          if obsyState != "Open":
             obsyState="Open Pending"
             pendingCount=1
          if obsyState == "Open Pending":
             pendingCount=1
          if pendingCount==maxPending:
             obsyState="Open"
             obsyOpen()
             ekosScheduler.loadScheduler('daily.esl')
             ekosScheduler.start()
             pendingCount=0
  
     time.sleep(60)
ekos.stop()

Since it’s not worth doing anything when the Sun is up, this routine calculates whether it’s up or not:

import astropy.coordinates as coord
def checkSun():
    loc = coord.EarthLocation(LONGITUDE * u.deg,LATITUDE * u.deg)
    now = Time.now()
    altaz = coord.AltAz(location=loc, obstime=now)
    sun = coord.get_sun(now).transform_to(altaz)
    if (sun.alt.degree > -6.0):
        logging.info("Sun is up")
        return True
    else:
        logging.info("Sun is down")
        return False

If we check the RG-11-based rain detector with getRain() and it returns true, or clouds are detected by our cloud detector software in AllSkyCam images, we do a roof close and cancel any currently executing schedules.   The code for these functions are below, details are in the articles linked above. Since I don’t want to load the model for the cloud detection every loop initialization is done elsewhere.

def getRain():
    try:
        ser = serial.Serial(getConfig(RAINPORT),2400,timeout=1)
        ser.flush()
        packet=ser.readline()
    except Exception as msg:
        logging.error("getRain error: "+msg)
    if (packet != b"safe#"):
        logging.info("Rain detected by Hydreon RG-11!")
        return True
    else:
        logging.info("Rain not detected by Hydreon RG-11.")
        return False
def mlCloudDetect():
      # Create a data array
      data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
      # Find the latest image in the allsky cam
      image = Image.open("mlCloudDetect/latest.jpg").convert("RGB")
      # resize the image and crop
      size = (224, 224)
      image = ImageOps.fit(image, size, Image.Resampling.LANCZOS)
      # turn the image into a numpy array
      image_array = np.asarray(image)
      # Normalize the image
      norm_image_array = (image_array.astype(np.float32) / 127.5) - 1
      # Load the image into the array
      data[0] = norm_image_array
      # Run the Keras model
      prediction = model.predict(data)
      index = np.argmax(prediction)
      class_name = class_names[index]
      return (class_name != 'Clear')

I also pull weather information in the form of wind speed from an Argent ADS-WS1 weather station.  Thanks to Evan Vander Stoep for most of this code.

def getWeather():
     try:
          ser = serial.Serial(getConfig(WEATHERPORT),2400,timeout=1)
          ser.flush()
          packet=ser.readline()
      except Exception as msg:
          logging.error("getWeather error: "+msg)
          return False
       
      header = packet[0:2]
      eom = packet[50:55]
      if header == b"!!" and eom == b"\r\n":
           # Wind Speed Calculations
           wind_speed = int(codecs.decode(packet[2:6], 'UTF-8'), 16)
           wind_speed = (wind_speed / 10)
           wind_speed = (wind_speed / 1.609344)
           wind_speed = round(wind_speed , 1)
           wx_wind_speed = wind_speed
 
           # Average Wind Speed Calculations
           average_wind_speed = int(codecs.decode(packet[46:50],
                                 'UTF-8'), 16)
           average_wind_speed = (average_wind_speed / 10)
           average_wind_speed = (average_wind_speed / 1.609344)
           average_wind_speed = round(average_wind_speed , 1)
           wx_average_wind_speed = average_wind_speed

           # Determine whether we should open dome
           if (wx_average_wind_speed < MAXAVWIND)
               and (wx_wind_speed < MAXWIND):
               return True
           else:
               return False
    else:
        logging.error("Unable to get weather data, returning False")
        return False

Because (as you can see below) my telescope needs to be parked before I can close the roof, the obsyClose() function parks the scope before the roof is closed. The function obsyOpen() also checks for parking before opening the roof.

 

scope.jpg

 

For INDI, we use PyIndi to communicate with the INDI server on the telescope computer. Since this is a network connection, we can run our code on any computer in the network and access remote devices. Similarly, since my observatory roof controller is on the network, I can control it from the telescope computer. INDI makes it very flexible as to where devices can reside on the network.

 

To connect to our INDI server, we do the following:

import PyIndi
indiclient=IndiClient()
indiclient.setServer(INDISERVER,INDIPORT)
logging.info('Connecting to INDI server')
if (not(indiclient.connectServer())):
    logging.error("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort()))
    sys.exit(1)

The IndiClient class below extends PyIndi.BaseClient so I can implement logging and other logic inside the class. Thanks to d33psky for this code.

class IndiClient(PyIndi.BaseClient):
  device=None
  imgIdx=0
  def __init__(self):
   super(IndiClient, self).__init__()
   self.logger = logging.getLogger('PyQtIndi.IndiClient')
   self.logger.info('creating an instance of PyQtIndi.IndiClient')
  def newDevice(self, d):
    self.logger.info("new device " + d.getDeviceName())
    if d.getDeviceName() == "CCD Simulator":
      self.logger.info("Set new device CCD Simulator!")
      # save reference to the device in member variable
      self.device = d
  def newProperty(self, p):
    self.logger.info("new property "+ p.getName() +
      " for device "+ p.getDeviceName())
    if (self.device is not None
        and p.getName() == "CONNECTION"
        and p.getDeviceName() == self.device.getDeviceName()):
      self.logger.info("Got property CONNECTION for CCD Simulator!")
      # connect to device
      self.connectDevice(self.device.getDeviceName())
      # set BLOB mode to BLOB_ALSO
      self.setBLOBMode(1, self.device.getDeviceName(), None)
  def removeProperty(self, p):
   self.logger.info("remove property "+ p.getName() +
     " for device "+ p.getDeviceName())
  def newSwitch(self, svp):
    self.logger.info ("new Switch "+ svp.name.decode() +
      " for device "+ svp.device.decode())
  def newNumber(self, nvp):
    self.logger.info("new Number "+ nvp.name +
      " for device "+ nvp.device)
  def newText(self, tvp):
    self.logger.info("new Text "+ tvp.name.decode() +
      " for device "+ tvp.device.decode())
  def newLight(self, lvp):
    self.logger.info("new Light "+ lvp.name.decode() +
      " for device "+ lvp.device.decode())
  def newMessage(self, d, m):
    self.logger.info("new Message "+ d.messageQueue(m))
  def serverConnected(self):
    print("Server connected ("+self.getHost()+":"+str(self.getPort())+")")
  def serverDisconnected(self, code):
    self.logger.info("Server disconnected (exit code = "+str(code)
      +","+str(self.getHost())+":"+str(self.getPort())+")")

To Park the telescope, we need to connect to it. Normally since this is a network operation we'd loop until we confirm the work is complete, with a timeout in case the device is offline etc. This is a typical INDI command - get the value of a Switch in a list, set the list members to the correct value for a particular attribute (in this case, TELESCOPE_PARK), and send it back to initiate the action.

# connect the scope
telescope='Telescope Simulator'
# get the telescope device
device_telescope=indiclient.getDevice(telescope)
# get a CONNECTION property be defined for telescope
telescope_connect=device_telescope.getSwitch("CONNECTION")
# if the telescope device is not connected, we do connect it
if not(device_telescope.isConnected()):
    telescope_connect[0].s=PyIndi.ISS_ON  # the "CONNECT" switch
    telescope_connect[1].s=PyIndi.ISS_OFF # the "DISCONNECT" switch
    indiclient.sendNewSwitch(telescope_connect)
else:
    logging.info('Telescope connected')

Finally, we parked the telescope and roll back the roof.   Once the command is sent, monitor the state until it’s no longer showing busy, recheck the status to ensure it’s parked, and close the roof. Since my INDI-based observatory controller is “in the shop” getting upgraded, I use a simple network relay controller to toggle the roof switch on and off to activate the Aleko sliding gate opener that controls the roof.

# Tell INDI to Park the scope
telescope_parkstatus=device_telescope.getSwitch("TELESCOPE_PARK")
telescope_parkstatus[0].s=PyIndi.ISS_ON   # the "PARK" switch
telescope_parkstatus[1].s=PyIndi.ISS_OFF  # the "UNPARKED" switch
indiclient.sendNewSwitch(telescope_parkstatus) # send new value
# Wait til the scope is finished moving
telescope_parkstatus=device_telescope.getSwitch("TELESCOPE_PARK")
while (telescope_parkstatus.getState()==PyIndi.IPS_BUSY):
     time.sleep(2)
     telescope_parkstatus=device_telescope.getSwitch("TELESCOPE_PARK")
# Double check parked status
telescope_parkstatus=device_telescope.getSwitch("TELESCOPE_PARK")
while not(telescope_parkstatus):
     time.sleep(0.5)
     telescope_parkstatus=device_telescope.getSwitch("TELESCOPE_PARK")
# Temporary use of network relay to open and close roof
# Turn on the first relay
url = 'http://10.0.0.101/30000/01'
response = requests.get(url)
# Wait
time.sleep(1)
# Turn it off again
url = 'http://10.0.0.101/30000/00'
response = requests.get(url)

The obsyClose() function is pretty much identical. Once I get my controller back in place, the INDI code will replace the temporary code to activate the roof.

 

The value of this code (which I run as a standalone program while doing things manually) was demonstrated the other night when I forgot to park the scope and initiated a close - I was scrambling to hit the STOP button when I realized the telescope was obediently parking itself and the roof didn't move to it had done so. Whew!! When the controller is back in the observatory there's actually an INDI function in the telescope and observatory drivers that lock the roof while the telescope is not parked and vice versa so this code won't be required but I may leave it in just in case!

 

The other issue I've run into is very occasionally my mount decides to not park in the correct position - I've got some Hall Effect Sensors and magnets that will be mounted on the telescope (remounted, actually, my first attempt didn't work so well) so I can detect exactly when the mount is in park position so I can never park it unless the scope is stowed. Something else waiting for some warmer weather!


Edited by gordtulloch, 25 February 2024 - 12:49 PM.

  • R Botero, Andreas_Roerig, CharLakeAstro and 1 other like this

#5 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 25 February 2024 - 12:56 PM

Right now my project is to write some Python code that will read in Ekos image sequence and schedule files so I can edit them and save them back to their XML file format.  That way I can generate target lists and write out a schedule that includes those lists for Ekos to execute every time the observatory is open. The beauty of this is I can have the software that generates the list adjust it for time of year, visibility of the objects, priority, etc. The overall effort will be an observatory control system named Obsy but all of these sub-projects will hopefully be useful to people as well.

 

The code uses a library called xmltodict to convert the XML format for the file to a Python dict data structure (basically keyword : value pairs) so it can more easily be manipulated (working with XML libraries made my head hurt!) and then it can convert the dict format back to XML for saving.

 

The repository for the Ekos file tools is at https://github.com/g...pythonEkosFiles. I have the sequence file pretty much done just starting on the schedule file.


Edited by gordtulloch, 25 February 2024 - 01:19 PM.

  • rpineau likes this

#6 CharLakeAstro

CharLakeAstro

    Vanguard

  • *****
  • Posts: 2,305
  • Joined: 12 Jan 2015

Posted 25 February 2024 - 10:59 PM

Thanks for sharing the code.

I am also working on park verification sensors, but using inductive proximity sensors with ferrous metal flags on the mount.

 

The other issue I've run into is very occasionally my mount decides to not park in the correct position - I've got some Hall Effect Sensors and magnets that will be mounted on the telescope (remounted, actually, my first attempt didn't work so well) so I can detect exactly when the mount is in park position so I can never park it unless the scope is stowed. Something else waiting for some warmer weather!



#7 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 26 February 2024 - 11:17 AM

Thanks for sharing the code.

I am also working on park verification sensors, but using inductive proximity sensors with ferrous metal flags on the mount.

Cool! Isn't the mount ferrous metal?



#8 archer1960

archer1960

    Soyuz

  • *****
  • Posts: 3,572
  • Joined: 26 Jul 2011
  • Loc: Southern New England

Posted 26 February 2024 - 07:28 PM

Cool! Isn't the mount ferrous metal?

Most of them are Aluminum on their outer shell and dovetail clamp.


  • CharLakeAstro likes this

#9 CharLakeAstro

CharLakeAstro

    Vanguard

  • *****
  • Posts: 2,305
  • Joined: 12 Jan 2015

Posted 27 February 2024 - 06:07 AM

Yes, machined aluminum.

The proximity sensor is shielded (threaded to the end) so the flag discrimination distance is small, ignoring anything but the flag.  

 

Most of them are Aluminum on their outer shell and dovetail clamp.


  • archer1960 likes this

#10 Broz22

Broz22

    Viking 1

  • *****
  • Posts: 785
  • Joined: 06 Sep 2020

Posted 27 February 2024 - 02:38 PM

Another proximity sensor you may want to consider to indicate mount parked is:

Sharp GP2Y0A21YK0F GP2Y0A21 10~80cm Infrared Proximity Distance Sensor at Amazon.

It is infrared (could interfere with imaging) with analog output, but I only power them after a park command is issued. I use a pair of these (ranges from the wall to the top and bottom of the OTA front ring) as backups to a digital IR laser beam breaking sensor (belt and suspenders). All 3 go into a Dragonfly along with the RG-11 and a future Cloudwatcher.

John



#11 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 27 February 2024 - 03:36 PM

Another proximity sensor you may want to consider to indicate mount parked is:

Sharp GP2Y0A21YK0F GP2Y0A21 10~80cm Infrared Proximity Distance Sensor at Amazon.

It is infrared (could interfere with imaging) with analog output, but I only power them after a park command is issued. I use a pair of these (ranges from the wall to the top and bottom of the OTA front ring) as backups to a digital IR laser beam breaking sensor (belt and suspenders). All 3 go into a Dragonfly along with the RG-11 and a future Cloudwatcher.

John

Very interesting and perhaps much easier than my magnet solution, but I'm having a bit of trouble visualizing the solution. I imagine you'd mount the device on the moving part of the roof and stop if you detect anything? Or is the light beam narrow enough to mount on the side wall and detect if the mount isn't low enough to clear the roof? 

 

Might be interesting to get one of these to experiment with!



#12 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 27 February 2024 - 04:09 PM

One thing I should mention is that some Linux distros such as Ubuntu wrap packaged applications in security "sandboxes" like AppArmor that protect the OS from misbehaving applications. Unfortunately they also block interprocess communications with things like D-bus so you either need to compile the application from source or turn it off (I always compile from source.)

 

If you want an easy way to install your Astro apps from source see:

 

https://gitea.nouspi...stro-soft-build



#13 Broz22

Broz22

    Viking 1

  • *****
  • Posts: 785
  • Joined: 06 Sep 2020

Posted 29 February 2024 - 03:12 PM

The analog distance sensor I mentioned is short range (~0.8m) with a fairly narrow beam. When my scope is parked (facing north), the front of the OTA is only ~30 cm from the wall, so I just mount a pair of them on the north wall to detect the top and bottom of the OTA front ring - the cdk is a tube truss with an ~1,5 cm wide upper ring. A reflected detection from these 2 is pretty positive indication that the mount is parked properly. The digital beam break has a tx/rx unit that sends out a narrow beam that is reflected back by a reflector unit. I mount the laser on the east wall and the reflector on the west wall so that the beam is broken (no reflection detected) when the OTA (truss shroud actually) is parked. I think the reflector can be up to ~ 35' away from the tx/rx unit, but mine is just 14' away. The beam must be pretty narrow since the reflector has to be carefully aligned to the other unit when setting up. A slight change in angle and the beam misses the rx unit. There are rare observing positions that might also break the beam partially motivating the desire for the redundant analog distance sensors. Probably not a worry since I don't energize the beam or distance sensors unless the RG-11 triggers to avoid shining IR led lasers around the shed while observing. The beam breaking laser unit (Seco-Larm E-931-S35RRQ Enforcer )was $49 and the distance sensors were $13. They have distance sensors that they say are good to 150 cm range.

John



#14 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 01 March 2024 - 01:40 PM

So you have the distance sensor AND a laser-based beam break setup?  Your distance sensor setup makes sense to me now, but since I swap OTAs a fair bit it'd be problematic.

 

At $6CDN each the Hall Effect Sensors (one each mounted on the RA and DEC axis) seem to be a lot more cost-effective than your setup and will detect that both the RA and DEC axis are in the right spots when the magnets are aligned with the sensor... my first attempt I didn't realize that the TOP of the sensor itself wouldn't detect the field, it is the side of the sensor that detects the field, so I just need to print some different mountings for them. Theoretically, if there's some slippage in the axis they may not return to the exact right spot, but that's fine, the roof won't close and will require intervention to determine why but I don't expect that'll happen.

 

I'll post on a separate thread how they work once the weather warms up (March is coming in like a lion, cold temps and lots of snow) and it's comfortable working in the shed. Probably after the trip to Mazatlan for the eclipse!!



#15 Broz22

Broz22

    Viking 1

  • *****
  • Posts: 785
  • Joined: 06 Sep 2020

Posted 03 March 2024 - 09:02 AM

gordtulloch,

Yes I use both after realizing that  the beam break triggered in more places than just park, and would do so pretty much however I mounted it. And 2 distance sensors are needed since a single one the way I have the placed them could be triggered if the Dec axis  ended up tilted up or down  ~ 10 degrees instead of the horizontal position I need for the roof to clear, Now the beam break is probably redundant since the distance sensors seem to work well, and I rarely remove the CDK14 (I have ta second saddle for other OTAs and currently have an 8" Newt there). I've left it in because I have extra sensors and relays available on the Dragonfly.

   Where did you get your Hall effect sensors, and do they just change a switch state when triggered? I'm very interested in your cloud detection work, but your installation explanation is probably over my head. I'll give it a try, but for now I'm even struggling with straight Indi- AllSky. I've got an HQ camera (IMX477)  working on a Pi4 running 64 bit Bullseye, but the pictures are garbled in AllSky.. Probably something wrong in my program or Pi configuration. The camera works fine when just testing it by itself. I'll keep plugging away. Thanks for all of your dev work. I think the AI approach is probably a big step up from the sky temp method. 

John



#16 Broz22

Broz22

    Viking 1

  • *****
  • Posts: 785
  • Joined: 06 Sep 2020

Posted 04 March 2024 - 03:22 PM

Sorry, Bookworm, not Bullseye.

John



#17 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 06 March 2024 - 02:15 PM

gordtulloch,

Yes I use both after realizing that  the beam break triggered in more places than just park, and would do so pretty much however I mounted it. And 2 distance sensors are needed since a single one the way I have the placed them could be triggered if the Dec axis  ended up tilted up or down  ~ 10 degrees instead of the horizontal position I need for the roof to clear, Now the beam break is probably redundant since the distance sensors seem to work well, and I rarely remove the CDK14 (I have ta second saddle for other OTAs and currently have an 8" Newt there). I've left it in because I have extra sensors and relays available on the Dragonfly.

   Where did you get your Hall effect sensors, and do they just change a switch state when triggered? I'm very interested in your cloud detection work, but your installation explanation is probably over my head. I'll give it a try, but for now I'm even struggling with straight Indi- AllSky. I've got an HQ camera (IMX477)  working on a Pi4 running 64 bit Bullseye, but the pictures are garbled in AllSky.. Probably something wrong in my program or Pi configuration. The camera works fine when just testing it by itself. I'll keep plugging away. Thanks for all of your dev work. I think the AI approach is probably a big step up from the sky temp method. 

John

I'm big on the "Belt and Suspenders" approach to not wrecking my scope with the roof so I'll look into the laser thing when I get working on the shed again (kinda cool right now, ok for observing with clear skies after a horrible winter, but not so much for sitting in the observatory adding stuff!)

 

Hall Effect Sensors are from Amazon (link).  The sensor needs +5v/GND and has a digital out pin that you can connect to an Arduino or similar device to detect when it's "closed" ie sensing a magnetic field. Fairly low sensitivity so the magnet needs to be right there to detect, which is fine since you don't want things stopping far away on either side of the sensor.  After initially deciding the modify the observatory controller software (based on the indi-rolloffino driver)  to check for two closed sensors I decided to build a little Arduino circuit in it's own case attached to the main observatory computer via USB so working on that now.  I'll post a thread when it's done with details.

 

I just updated the mlCloudDetect github repo with installation instructions if that helps at https://github.com/g...h/mlCloudDetect


Edited by gordtulloch, 06 March 2024 - 02:16 PM.


#18 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 06 March 2024 - 02:24 PM

Sorry, Bookworm, not Bullseye.

John

Aaron is very responsive in the thread on the Astronomy Software and Computers for INDI-Allsky if you haven't posted there already.



#19 lambermo

lambermo

    Apollo

  • -----
  • Posts: 1,281
  • Joined: 16 Jul 2007
  • Loc: .nl

Posted 06 March 2024 - 03:21 PM

Hi Gord, cool that you're doing this. It inspires me to continue my automation journey.
I've been using KStars/EKOS/INDI for a few years now with some extra tools that I wrote with full automation as a goal.
Side projects were writing some device drivers on the way, building an all-sky and a weather station whose outputs are used in a safety monitor.
One of these tools is what I called ekos_sentinel.py (also using D-Bus to EKOS), whose task is to monitor the safety monitors' output and act in case Kstars/EKOS crashes to park the mount and close the roof.
I've used this system on several nights over the last few years.
The weather station also uses an RG-11, but then in drop-detection mode. The safety monitor compensates for the occasional dew 'drop' and uses hysteresis to determine when the roof can be re-opened so that it is not flip-flopping too often. UPS status is also part of the safety inputs, but its 2-weekly self-check has caused unneccesary roof closures for which I have no proper solution yet laugh.gif
Other problems are that over the years some sensors become unreliable or less sensitive (looking at you DHT22 and Melexis BAA and especially BCC). I need to replace those.
Next I'm adding a second independent park sensor. I need the roof to not be able to move when the mount is not properly parked.
I have not yet put any work in managing the scheduler, so I'm happy to see that you already have.
All my code lives in https://github.com/d33psky/rolloffroof and I've been wanting to clean that up and rewrite most of it for some years now laugh.gif

-- Hans



#20 gordtulloch

gordtulloch

    Apollo

  • *****
  • topic starter
  • Posts: 1,191
  • Joined: 10 Feb 2005
  • Loc: Winnipeg Canada

Posted 06 March 2024 - 03:45 PM

Hi Hans! I'm sure I lifted some code or at least some knowledge from ekos_sentinal, thank you very much :)  I grew up as a C programmer, so your more OOPS approach is very helpful in understanding how I might enhance my code. Definitely my MCP program is inspired by ekos_sentinal. I'm a bit leery of being too reliant on INDI as it can stop working with updates, at least if I control everything if I break it I can fix it!  I definitely don't want the mount park detectors running through INDI, it should be an independant check.

 

A lot of the impetus for this project is to provide a worker bee to be coordinated by a web user interface, I've started working on that now. Basically the combination should be pretty close to an open source version of DC3 Dreams' ACP software they use for iTelescope. My desire for a completely automated observatory was reinforced Monday night when it was the first clear night in a week and I was stuck taking my wife to a concert while the observatory sat idle! I'm struggling with some focusing challenges right now so all the automation stuff is turned off for a bit til I can build a MyFocuserPro2 and retrofit my SCT with an external focuser. 



#21 Broz22

Broz22

    Viking 1

  • *****
  • Posts: 785
  • Joined: 06 Sep 2020

Posted 07 March 2024 - 09:22 AM

Thanks Gordon,

John




CNers have asked about a donation box for Cloudy Nights over the years, so here you go. Donation is not required by any means, so please enjoy your stay.


Recent Topics






Cloudy Nights LLC
Cloudy Nights Sponsor: Astronomics