Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird termination #1

Open
spirrobe opened this issue Dec 12, 2023 · 0 comments
Open

Weird termination #1

spirrobe opened this issue Dec 12, 2023 · 0 comments

Comments

@spirrobe
Copy link

Hi

We would like to conduct repeated RHI and (partial) PPI scans via the RadarControl.py.

For this purpose we wrote the following script below (work in progress) for the RHI scan which is basically going down once from 90° and going back up to 90°. This should run for a number of times, until a certain amount of time has passed.

Basically, we create 2 SCANS (as the definition of them does not allow for backwards movement), write the MDF file in a loop for the number of scans/2 we want to do and send that via the client.start_radar_measurement_local_mdf(MDFFILE). As the client is non-blocking it is actually unclear how long we should wait and this is calculated based on the scanspeed + scanrange.

However, the termination / return to previous zenith MDF proves tricky. Hence the functions ensure_termination and ensure_start which in reality just spam the dataserver/radar every 1 second until success or a maximum of 20 seconds and check the return codes. The reality is however that one can just send the previous zenith again and even when the return code states radar not in STANDBY mode the MDF will start again.

Can you provide a bit more clarity about how the termination, the return code and the start of such repeated measurements should look like?

Additionally, when having 2 clients (i.e. seperate python sessions) to check the measurements via

for i in range(120):
    s = c.get_last_sample()
    print(s.elv)
    time.sleep(2)

There is a missmatch between GUI and the reported values

# -*- coding: utf-8 -*-
"""
Created on Wed Dec  6 13:44:33 2023

@author: Toshiba
"""
import os, time, sys, glob
import numpy as np

from RPGtools_RemoteSensingInstruments.RadarControl import(Scan,
                                                           Client,
                                                           MeasDefFile,
                                                           install_local_mdf, 
                                                           get_radar_status,
                                                           start_radar_measurements_local_mdf,
                                                           start_radar_measurements,
                                                           install_local_mdf)

WORKDIR = os.path.abspath('.')
WORKDIR = WORKDIR  if WORKDIR.endswith(os.sep) else WORKDIR + os.sep

##################################
### RADAR SPECIFIC SETTINGS ######
##################################
IP = '192.168.0.2'
PORT = 7000
PW = ''
CONFIG = [IP, PORT, PW]

##################################
### CHIRP SPECIFIC SETTINGS ######
##################################
CHIRPPRG = 8 #RMBLCHIRP, the inface number starts at 1, the real list at 0

##################################
### LOCATION SPECIFIC SETTINGS ###
##################################
NORTHOFFSET = 22.3

##################################
### CLOUDLAB SPECIFIC SETTINGS ###
##################################
#default duration is in s
DURATION = 20 * 60 
EXTRAWAIT = 10 # an extra number of seconds to wait for the scan to be done
# at the end of a scan, wait this amount in seconds before sending a new scan cmd
AFTERSCANWAIT = 5

def ensure_termination(client,
                       timeout=20,
                       retrytime=0.5,
                       quiet=True):
    res = -1
    cnt = 0
    while res != 1:
        if not quiet:
            print(f'Trying to terminate measurements (try {cnt+1})')
        res = client.terminate_radar_measurements()
        
        if res in [3, 4]:
            print('Zero calibration cannot be determinated, wait longer...')
            try:
                time.sleep(1)
            except KeyboardInterrupt:
                print('Waiting cancelled')
                return
        elif res in [5]:
            print('Transmitter calibration cannot be determinated, wait longer...')
            time.sleep(10)
            
        time.sleep(retrytime)
        cnt += 1
        _status = client.get_radar_status()
        # print('Current status after termination command:', _status.__dict__)
        if cnt * retrytime >= timeout:
            print(f'Measurement could not be terminated in {cnt} seconds, use GUI')
            return

    # to ensure there is enough time for the radar to react
    time.sleep(2)

def ensure_start(client,
                 file,
                 timeout=20,
                 retrytime=0.5,
                 quiet=True):

    res = -1
    cnt = 0
    client.terminate_radar_measurements()
    while res != 1:
        if not quiet:
            print(f'Trying to start measurements (try {cnt+1})')
        
        # if the file exists we assume it is a local file that we do once
        #else we assume it is on the radar in the default MDF/MBF directory
        if os.path.exists(file):
            # assume its local and we need to send it
            res = client.start_radar_measurements_local_mdf(file)
        else:
            # assume its on the radar
            res = client.start_radar_measurements(file)

        # if res == 2:
        #     ensure_termination(client, quiet=quiet)

        time.sleep(retrytime)
        cnt += 1
        _status = client.get_radar_status()
        # print('Current status after termination command:', _status.__dict__)
        if cnt * retrytime >= timeout:
            print(f'Measurement could not be started in {cnt} seconds, use GUI')
            return

    # to ensure there is enough time for the radar to react
    time.sleep(2)

def scan_elevation(elevation_init, 
                   elevation_end, 
                   azimuth,
                   # at which speed to scan
                   scanspeed=1.0, 
                   # at which speed to move
                   fastspeed=5.0, 
                   # this is the LOWER scantime, as it will be updated
                   # to match an even number of scans with the given speed/angle
                   totalduration=DURATION,
                   # the calibration interval (abs. cal.). be aware that once
                   # this is running the scan cannot be aborted
                   calibration_interval=1,
                   quiet=True,
                   dryrun=True):
    try:
        c = Client(*CONFIG, SuppressOutput=False,)#quiet)    
    except:
        print('Error connecting to data server, returning ...')
        return
    
    movementtime = int(np.ceil((azimuth-NORTHOFFSET) / fastspeed))
    
    onescanduration = (abs(elevation_end - elevation_init)/scanspeed)
    onescanduration = int(onescanduration)
    
    nscans = totalduration / onescanduration
    nscans = int(np.ceil(nscans))
    # these have to be symmetrical, so always needs to be an even number
    if nscans % 2 != 0:
        print('Adding another scancycle to return radar to zenith')
        nscans += 1
        
    totalduration = int(nscans * onescanduration)
    
    print(f'The scanrange of {elevation_init}° to {elevation_end}° with',
          f'a speed of {scanspeed} results in {nscans} scans for {totalduration} seconds',
          '(This was rounded up to match the next higher duration including return)')
    # the first scan (e.g. going down)    
    SCAN_FORTH = Scan(elv=elevation_init, 
                      azm=((azimuth-NORTHOFFSET)+360)%360, 
                      elv_target=elevation_end, 
                      azm_target=((azimuth-NORTHOFFSET)+360)%360, 
                      elv_spd=scanspeed,
                      azm_spd=fastspeed,
                      )
    # the second scan (e.g. going back up)
    SCAN_BACK = Scan(elv=elevation_end, 
                     azm=((azimuth-NORTHOFFSET)+360)%360, 
                     elv_target=elevation_init, 
                     azm_target=((azimuth-NORTHOFFSET)+360)%360, 
                     elv_spd=scanspeed,
                     azm_spd=fastspeed,
                     )
    
    radar_status = c.get_radar_status()
    if 'mdf_name' in radar_status.__dict__:
        oldmdf = radar_status.mdf_name
    else:
        oldmdf = None
    
    if isinstance(oldmdf, list):
        oldmdf = oldmdf[0]
        
    print(f'Radar is currently running {oldmdf}\n')
    
    # ensure termination of radar measurements
    # if not dryrun:
    #     try:
    #         ensure_termination(c, quiet=quiet)
    #     except KeyboardInterrupt:
    #         print('Cancellation of scanning...')
    #         if oldmdf is not None:
    #             print(f'Installing previous MDF: {oldmdf}')
    #             ensure_start(c, oldmdf)
    #         return
    #     finally:
    #         pass

            
    radar_id = c.get_radar_id()

    m = MeasDefFile()
    f = 'elevation_scan.mdf'
    
    if dryrun:
        m.create(WORKDIR + f, CHIRPPRG, SCAN_FORTH, 
                 duration=totalduration,
                 filelen=totalduration,
                 cal_int=calibration_interval,
                 )
        m.read(WORKDIR + f)
        print(f'Running {WORKDIR+f}:')
        m.output()
        os.remove(WORKDIR + f)
    else:
        try:
            print(f'A Running {WORKDIR+f}:')
            # m.create(WORKDIR + f, CHIRPPRG, SCAN_FORTH, duration=totalduration)
            
            # ensure_termination(c, quiet=quiet)
            for iscan in range(int(np.ceil(nscans/2))):
                print(f'Running {iscan*2+1} of {nscans}:')
                m.create(WORKDIR + f, CHIRPPRG, SCAN_FORTH,
                         duration=onescanduration,
                         filelen=onescanduration,
                         cal_int=calibration_interval,
                         )
                m.read(WORKDIR + f)

                # ensure_termination(c, quiet=quiet) 
                ensure_start(c, WORKDIR+f)
                # some time for movement in azimuth for the first scan
                if iscan == 0:
                    time.sleep(max([1, movementtime]))
                time.sleep(onescanduration + 5)
                time.sleep(AFTERSCANWAIT)
                # ensure_termination(c, quiet=quiet)
                # os.remove(WORKDIR + f)
                
                print(f'Running {iscan*2+2} of {nscans}:')
                m.create(WORKDIR + f, CHIRPPRG, SCAN_BACK,
                         duration=onescanduration,
                         filelen=onescanduration,
                         cal_int=calibration_interval,
                         )
                m.read(WORKDIR + f)
                # ensure_termination(c, quiet=quiet)
                ensure_start(c, WORKDIR+f)

                time.sleep(onescanduration + 5)
                time.sleep(AFTERSCANWAIT)
                # ensure_termination(c, quiet=quiet)
                # os.remove(WORKDIR + f)
        except KeyboardInterrupt:
            print('Stopping scanning operation...')
        finally:
            ensure_termination(c)
        print('Scan finished (see above if successful).')
        if oldmdf is not None:
            print(f'Installing previous MDF: {oldmdf}')
            # time.sleep(15)
            # ensure_termination(c)
            time.sleep(10)
            c.terminate_radar_measurements()
            ensure_start(c, oldmdf)
    
    # ensure some wait before killing the client
    time.sleep(5)
    return c
    # del c

if __name__ == '__main__':
    pass
    # a half rhi at geographical 0° 
    client = scan_elevation(90, 45, NORTHOFFSET, 
                            totalduration=20, 
                            dryrun=False,
                            quiet=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant