Source code for blindorientation

#!/usr/bin/env python
"""
.. module:: blindorientation.py

.. moduleauthor:: Zoltan Siki

Get orientation for totalstation. Command line parameters::

    argv[1]: input coordinate file

"""
import sys
import re
import math
import logging
import os.path

# 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, PI2
from totalstation import TotalStation

[docs]class Orientation(object): """ find prism and orientation from coordinate list :param observations: list of observation :param ts: totalstation :param dist_tol: distance tolerance, default 0.1 m """ def __init__(self, observations, ts, dist_tol=0.1): """ initialize """ self.dist_tol = dist_tol self.step = 3.0 / 180.0 * math.pi # 3 arc deg self.observations = observations self.ts = ts
[docs] def FindPoint(self, obs): """ Find point from observation (distance and zenith) compering slope distances and heigth differences :param obs: observation data :returns: bearing to actual instrument direction """ if 'distance' not in obs or 'v' not in obs: return None d_elev = obs['distance'] * math.cos(obs['v'].GetAngle()) min_o = None mind = 1e10 # find nearest point for o in self.observations: if 'distance' in o and 'v' in o: d_elev1 = o['distance'] * math.cos(o['v'].GetAngle()) dd = abs(o['distance'] - obs['distance']) de = abs(d_elev1 - d_elev) if dd < self.dist_tol and de < self.dist_tol: ddd = math.sqrt(dd * dd + de * de) if mind > ddd: mind = ddd min_o = o if min_o: return min_o['hz'] return None
[docs] def Search(self): """ Search for a prism :returns: dictionary on error with errorCode """ self.ts.GetATR() # wake up instrument dhz = 0 # relative direction from start position # find min/max zenith angles min_v = math.pi max_v = 0 for obs in self.observations: if 'v' in obs: if min_v > obs['v'].GetAngle(): min_v = obs['v'].GetAngle() if max_v < obs['v'].GetAngle(): max_v = obs['v'].GetAngle() self.ts.SetATR(1) self.ts.SetEDMMode('STANDARD') ans = self.ts.GetAngles() if not 'v' in ans: logging.fatal("Check communication line") sys.exit(1) # move from safe position to first direction if ans['v'].GetAngle('DEG') > 160 and ans['v'].GetAngle('DEG') < 200: ans = self.ts.Move(self.observations[1]['hz'], \ self.observations[1]['v'], 0) # instrument targeting on prism? ans = self.ts.MoveRel(Angle(0), Angle(0), 1) if 'errorCode' in ans: # try to rotate to the second, third, ... point i = 2 while 'errorCode' in ans and i < len(self.observations): ans = self.ts.Move(self.observations[i]['hz'], \ self.observations[i]['v'], 1) i += 1 if 'errorCode' in ans: # try powersearch clockwise if 'POWERSEARCH' in self.ts.measureUnit.GetCapabilities(): # set telescope into the middle in vertical direction angles = self.ts.GetAngles() self.ts.Move(angles['hz'], Angle((min_v + max_v) / 2.0)) # repeat power search to skip false prisms for i in range(10): ans = self.ts.PowerSearch(1) if 'errorCode' not in ans: self.ts.Measure() obs = self.ts.GetMeasure() w = self.FindPoint(obs) if w is not None: ans = self.ts.SetOri(w) return ans if 'errorCode' not in ans: self.ts.Measure() obs = self.ts.GetMeasure() w = self.FindPoint(obs) if w is not None: ans = self.ts.SetOri(w) return ans # try blind find angles = self.ts.GetAngles() if 'errorCode' in angles: logging.error("Cannot measure angles") return angles if 'hz' not in angles: logging.error("No Hz got from instrument") angles['errorCode'] = 999 return angles act_hz = angles['hz'].GetAngle() while dhz < PI2: act_v = min_v while act_v <= max_v: ans = self.ts.Move(Angle(act_hz), Angle(act_v), 1) if 'errorCode' not in ans: self.ts.Measure() obs = self.ts.GetMeasure() w = self.FindPoint(obs) if w is not None: ans = self.ts.SetOri(w) return ans act_v += self.step act_hz += self.step if act_hz > 2 * math.pi: act_hz -= 2* math.pi dhz += self.step return {'errCode': -999}
if __name__ == '__main__': from serialiface import SerialIface from georeader import GeoReader from csvreader import CsvReader logging.getLogger().setLevel(logging.WARNING) if len(sys.argv) > 1: ifname = sys.argv[1] else: #ifname = 'test.geo' print("Usage: blindorientation.py input_file totalstation port") sys.exit(-1) if ifname[-4:] != '.dmp' and ifname[-4:] != '.geo': ifname += '.geo' if ifname[-4:] == '.geo': g = GeoReader(fname=ifname) else: g = CsvReader(fname=ifname) if g.state == g.RD_OPEN: sys.exit(2) data = g.Load() stationtype = '1100' if len(sys.argv) > 2: stationtype = sys.argv[2] port = '/dev/ttyUSB0' if len(sys.argv) > 3: port = sys.argv[3] if re.search('120[0-9]$', stationtype): from leicatps1200 import LeicaTPS1200 mu = LeicaTPS1200() elif re.search('110[0-9]$', stationtype): from leicatcra1100 import LeicaTCRA1100 mu = LeicaTCRA1100() elif re.search('180[0-9]$', stationtype): from leicatca1800 import LeicaTCA1800 mu = LeicaTCA1800() elif re.search('550[0-9]$', stationtype): from trimble5500 import Trimble5500 mu = Trimble5500() iface = SerialIface("rs-232", port) ts = TotalStation(stationtype, mu, iface) o = Orientation(data, ts) print(o.Search())