Source code for measuretoprism

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
.. module:: measuretoprism.py

.. moduleauthor:: dr. Zoltan Siki <siki@agt.bme.hu>, Viktoria Zubaly, Daniel Moka <mokadaniel@citromail.hu>

Sample application of Ulyxes PyAPI to measure to a moving prism/object.
    Select different modes for different scenarios<br>
    0 - determine the horizontal movement of a bridge pylon without prism using
    edm mode RLSTANDARD<br>
    1 - determine the movement of a slowly moving prism to determine 3D defomation<br>
    2 - determine vertical movement of a prism, deflection of a bridge, we suppose horizontal distance is not changed (without lock ATR targeting before angles<br>
    3 - determine vertical movement of a moving prism, we suppose horizontal distance is not changedi (lock on prism)<br>
    4 - determine 3D movement of a moving prism on a car/machine (lock on prism)<br>
    5 - measure points if the prism stopped for 3-5 seconds (lock on prism)<br>

    :param argv[1] (sensor): 110n/180n/120n, default 1200
    :param argv[2] (mode): 0/1/2/3/4/5 without ATR/with ATR/with ATR no distance/lock single distance/lock with distance/store if stopped, default 4
    :param argv[3] (edm): edm mode STANDARD/FAST, default FAST
    :param argv[4] (port): serial port, use a filename for local iface, default COM7
    :param argv[5] (file): output file, data are appended to the end of the file
"""
import re
import sys
import logging
import math
import os.path
import signal

# check PYTHONPATH
if len([p for p in sys.path if 'pyapi' in p]) == 0:
    if os.path.isdir('../pyapi/'):
        sys.path.append('../pyapi/')
    else:
        print("pyapi not found")
        print("Add pyapi directory to the Python path or start your application from ulyxes/pyapps folder")
        sys.exit(1)

from angle import Angle
from serialiface import SerialIface
from totalstation import TotalStation
from localiface import LocalIface
from csvwriter import CsvWriter
from echowriter import EchoWriter
from leicatcra1100 import LeicaTCRA1100
from leicatca1800 import LeicaTCA1800
from leicatps1200 import LeicaTPS1200
from trimble5500 import Trimble5500

[docs]def exit_on_ctrl_c(signal, frame): """ catch interrupt (Ctrl/C) and exit gracefully """ print("\nCtrl/C was pressed, exiting...") sys.exit(0)
if __name__ == "__main__": logging.getLogger().setLevel(logging.ERROR) # Process command line parameters if len(sys.argv) == 1: print('Usage: {} instrument [mode [EDM_mode [serial [output_csv]]]]'.format(sys.argv[0])) exit() # Instrument type if len(sys.argv) > 1: if re.search('110[0-9]$', sys.argv[1]): mu = LeicaTCRA1100() elif re.search('180[0-9]$', sys.argv[1]): mu = LeicaTCA1800() elif re.search('120[0-9]$', sys.argv[1]): mu = LeicaTPS1200() elif re.search('550[0-9]$', sys.argv[1]): mu = Trimble5500() else: mu = LeicaTPS1200() else: mu = LeicaTPS1200() # Measure mode mode = 4 # lock with distance measurement if len(sys.argv) > 2: try: mode = int(sys.argv[2]) except ValueError: mode = 4 # EDM mode edm = 'FAST' if len(sys.argv) > 3: edm = sys.argv[3] # Serial port com = '/dev/ttyUSB0' if len(sys.argv) > 4: com = sys.argv[4] if re.search('^COM[0-9]+', com) or re.search('^/dev/.*tty', com): iface = SerialIface("rs-232", com) else: iface = LocalIface("testIface", com) # Local iface for testing the module if iface.state != iface.IF_OK: sys.exit(1) # Writer if len(sys.argv) > 5: wrt = CsvWriter(angle='GON', dist='.3f', dt='%Y-%m-%d %H:%M:%S.%f', filt=['id', 'datetime', 'hz', 'v', 'distance', 'east', 'north', 'elev'], fname=sys.argv[5], mode='a', sep=';') else: wrt = EchoWriter(angle='GON', dist='.3f', dt='%Y-%m-%d %H:%M:%S.%f', filt=['id', 'datetime', 'hz', 'v', 'distance', 'east', 'north', 'elev']) signal.signal(signal.SIGINT, exit_on_ctrl_c) # catch Ctrl/C ts = TotalStation("Leica", mu, iface) slopeDist = 0 if edm not in mu.edmModes: edm = 'FAST' ts.SetEDMMode(edm) # initialize instrument and variables if mode > 0: ts.SetLock(0) ts.SetATR(1) ts.MoveRel(Angle(0), Angle(0), 1) ts.Measure() measurement = ts.GetMeasure() if 'distance' in measurement: slopeDist = measurement['distance'] if mode in (3, 4, 5): ts.SetLock(1) ts.LockIn() if mode == 5: last_hz = measurement['hz'] # direction of last measured point last_v = measurement['v'] prev_hz = measurement['hz'] # direction of last measured point prev_v = measurement['v'] moving = True limit = Angle('0-03-00', 'DMS') # minimal angle change to measure n = 0 else: try: ts.SetATR(0) except: pass # infinite loop of measuring while ts.measureIface.state == ts.measureIface.IF_OK: if mode == 0: ts.Measure() # distance measurement without ATR measurement = ts.GetMeasure() elif mode == 1: ts.MoveRel(Angle(0), Angle(0), 1) # aim on target with ATR ts.Measure() measurement = ts.GetMeasure() elif mode == 2: # aim on target with ATR without distance measurements ts.MoveRel(Angle(0), Angle(0), 1) measurement = ts.GetAngles() elif mode == 3: measurement = ts.GetAngles() # get angles only elif mode == 4: # get distance measurement with targeting mode ts.Measure() measurement = ts.GetMeasure() elif mode == 5: # go and stop, store full measurements within the limitation measurement = ts.GetAngles() if moving: if abs(prev_hz.GetAngle() - measurement['hz'].GetAngle()) < limit.GetAngle() and \ abs(prev_v.GetAngle() - measurement['v'].GetAngle()) < limit.GetAngle(): n += 1 # store if the measured values within the angle limitation three times if n <= 3: continue ts.Measure() measurement = ts.GetMeasure() moving = False # approximately standing last_hz = measurement['hz'] # direction of last stored point last_v = measurement['v'] prev_hz = measurement['hz'] # direction of last examined point prev_v = measurement['v'] n = 0 # start counting again if the last examind point is stored else: prev_hz = measurement['hz'] prev_v = measurement['v'] continue else: if abs(last_hz.GetAngle() - measurement['hz'].GetAngle()) >= limit.GetAngle() or \ abs(last_v.GetAngle() - measurement['v'].GetAngle()) >= limit.GetAngle(): moving = True # still moving continue # Get each measurement data if 'distance' in measurement: # Check existance of 'distance' key slopeDist = measurement['distance'] if 'hz' in measurement: # Check existence of 'hz' key hz = measurement['hz'] if 'v' in measurement: # Check existence of 'v' key v = measurement['v'] # Compute relative coordinates according to the instrument origin if 'hz' in measurement and 'v' in measurement: measurement['east'] = slopeDist * math.sin(v.GetAngle()) * \ math.sin(hz.GetAngle()) measurement['north'] = slopeDist * math.sin(v.GetAngle()) * \ math.cos(hz.GetAngle()) measurement['elev'] = slopeDist * math.cos(v.GetAngle()) # Store in file the measurements wrt.WriteData(measurement) #print(measurement) else: print("Some measurement data(s) are missing...")