Example #1
0
    def testWrap(self):
        for wrap in (-1000, -10, -1, 0, 1, 10, 1000):
            for offset in (-360, -180, -90, 0, 90, 180, 270, 360):
                for epsMult in (-3, -2, -1, 0, 1, 2, 3):
                    ang = offset + (wrap * 360)
                    ang += ang * DoubleEpsilon * epsMult
                    sinAng = sind(ang)
                    cosAng = cosd(ang)
                    pvt = PVT(ang, ang, 35.0)  # pick anything for vel and time

                    posAng = wrapPos(ang)
                    self.assertGreaterEqual(posAng, 0.0)
                    self.assertLess(posAng, 360.0)
                    # prove that posAng and ang are the same angle
                    # sin and cos are a sanity check on wrapCtr
                    self.assertAlmostEqual(wrapCtr(posAng - ang), 0)
                    self.assertAlmostEqual(sind(posAng), sinAng)
                    self.assertAlmostEqual(cosd(posAng), cosAng)

                    posPvt = wrapPos(pvt)
                    self.assertEqual(posPvt.pos, posAng)
                    self.assertEqual(posPvt.vel, pvt.vel)
                    self.assertEqual(posPvt.t, pvt.t)

                    ctrAng = wrapCtr(ang)
                    self.assertGreaterEqual(ctrAng, -180.0)
                    self.assertLess(ctrAng, 180.0)
                    # prove that ctrAng and ang are the same angle
                    self.assertAlmostEqual(wrapCtr(ctrAng - ang), 0)
                    self.assertAlmostEqual(sind(ctrAng), sinAng)
                    self.assertAlmostEqual(cosd(ctrAng), cosAng)

                    ctrPvt = wrapCtr(pvt)
                    self.assertEqual(ctrPvt.pos, ctrAng)
                    self.assertEqual(ctrPvt.vel, pvt.vel)
                    self.assertEqual(ctrPvt.t, pvt.t)

                    for refAngBase in (-180, 0, 180, 360):
                        for refEpsMult in (-3, -2, -1, 0, 1, 2, 3):
                            refAng = refAngBase
                            refAng += refAng * refEpsMult * DoubleEpsilon
                            nearAng = wrapNear(ang, refAng)
                            self.assertGreaterEqual(nearAng - refAng, -180)
                            self.assertLess(nearAng - refAng, 180)
                            # prove that nearAng and ang are the same angle
                            self.assertAlmostEqual(wrapCtr(nearAng - ang), 0)
                            self.assertAlmostEqual(sind(nearAng), sinAng)
                            self.assertAlmostEqual(cosd(nearAng), cosAng)
    def testWrap(self):
        for wrap in (-1000, -10, -1, 0, 1, 10, 1000):
            for offset in (-360, -180, -90, 0, 90, 180, 270, 360):
                for epsMult in (-3, -2, -1, 0, 1, 2, 3):
                    ang = offset + (wrap * 360)
                    ang += ang * DoubleEpsilon * epsMult
                    sinAng = sind(ang)
                    cosAng = cosd(ang)
                    pvt = PVT(ang, ang, 35.0) # pick anything for vel and time

                    posAng = wrapPos(ang)
                    self.assertGreaterEqual(posAng, 0.0)
                    self.assertLess(posAng, 360.0)
                    # prove that posAng and ang are the same angle
                    # sin and cos are a sanity check on wrapCtr
                    self.assertAlmostEqual(wrapCtr(posAng - ang), 0)
                    self.assertAlmostEqual(sind(posAng), sinAng)
                    self.assertAlmostEqual(cosd(posAng), cosAng)

                    posPvt = wrapPos(pvt)
                    self.assertEqual(posPvt.pos, posAng)
                    self.assertEqual(posPvt.vel, pvt.vel)
                    self.assertEqual(posPvt.t, pvt.t)

                    ctrAng = wrapCtr(ang)
                    self.assertGreaterEqual(ctrAng, -180.0)
                    self.assertLess(ctrAng, 180.0)
                    # prove that ctrAng and ang are the same angle
                    self.assertAlmostEqual(wrapCtr(ctrAng - ang), 0)
                    self.assertAlmostEqual(sind(ctrAng), sinAng)
                    self.assertAlmostEqual(cosd(ctrAng), cosAng)

                    ctrPvt = wrapCtr(pvt)
                    self.assertEqual(ctrPvt.pos, ctrAng)
                    self.assertEqual(ctrPvt.vel, pvt.vel)
                    self.assertEqual(ctrPvt.t, pvt.t)
                    
                    for refAngBase in (-180, 0, 180, 360):
                        for refEpsMult in (-3, -2, -1, 0, 1, 2, 3):
                            refAng = refAngBase
                            refAng += refAng * refEpsMult * DoubleEpsilon
                            nearAng = wrapNear(ang, refAng)
                            self.assertGreaterEqual(nearAng - refAng, -180)
                            self.assertLess(nearAng - refAng, 180)
                            # prove that nearAng and ang are the same angle
                            self.assertAlmostEqual(wrapCtr(nearAng - ang), 0)
                            self.assertAlmostEqual(sind(nearAng), sinAng)
                            self.assertAlmostEqual(cosd(nearAng), cosAng)
def makePVTFromPair(posPair, tai, deltaT, isAngle):
    pos = posPair[0]
    if (isAngle):
        vel = coordConv.wrapCtr(posPair[1] - posPair[0]) / deltaT
    else:
        vel = (posPair[1] - posPair[0]) / deltaT
    return coordConv.PVT(pos, vel, tai)
def measureOrientationToErr():
    """Measure error in Coord.orientationTo for tiny offsets
    
    For best results modify Coord::orientationTo to not short-circuit tiny values of sinVal, cosVal
    """
    errDict = {} # dict of distArcSec: (max orient error, max(sinVal, cosVal))
    for fromPolarAng in (-89, -72, -45.0, -30, 0.01, 12.5, 31, 47, 56, 68, 89):
        for fromEquatAng in (0, 41.0): # should not matter
            fromCoord = coordConv.Coord(fromEquatAng, fromPolarAng)
            for fromOrient in (-90, -72, -45.0, -30, 0.01, 0, 12.5, 31, 45, 56, 68, 89):
                # offset by such small distances that toOrient=fromOrient
                # by 1e-6 the error is starting to go up, indicating that the approximation is failing
                for distArcSec in (5e-5, 1e-4, 2e-4, 3e-4, 4e-4, 5e-4, 1e-3, 1e-2):
                    toCoord, dumToOrient = fromCoord.offset(fromOrient, distArcSec / 3600)
                    toOrient = coordConv.wrapCtr(180 + toCoord.orientationTo(fromCoord))

                    # expect fromOrient = toOrient
                    newErrArcSec = abs(toOrient - fromOrient) * 3600
                    oldErrArcSec = errDict.get(distArcSec, (0, 0))[0]
                    if newErrArcSec > oldErrArcSec:
                        toU = toCoord.getVecPos()
                        toU /= numpy.linalg.norm(toU)
                        fromU = fromCoord.getVecPos()
                        fromU /= numpy.linalg.norm(fromU)
                        sinVal = (toU[1] * fromU[0]) - (toU[0] * fromU[1])
                        cosVal = (toU[2] * ((fromU[0] * fromU[0]) + (fromU[1] * fromU[1]))) \
                                  - (fromU[2] * ((toU[0] * fromU[0]) + (toU[1] * fromU[1])))
                        errDict[distArcSec] = (newErrArcSec, max(sinVal, cosVal))
    distKeys = sorted(errDict.keys())
    print "Note that by 0.01 arcsec the error creeps up, indicating that the approximation toOrient=fromOrient is failing"
    for distArcSec in distKeys:
        errArcSec, maxSinCos = errDict[distArcSec]
        print "distArcSec=%0.3g arcsec, maxErr=%0.3g arcsec, maxSin/Cos=%0.3g" % (distArcSec, errArcSec, maxSinCos)
def makePVTFromPair(posPair, tai, deltaT, isAngle):
    pos = posPair[0]
    if (isAngle):
        vel = coordConv.wrapCtr(posPair[1] - posPair[0]) / deltaT
    else:
        vel = (posPair[1] - posPair[0]) / deltaT
    return coordConv.PVT(pos, vel, tai)
Example #6
0
def refPolarFromXY(x, y, tai):
    """Reference implementation of PVT.polarFromXY
    """
    atPole = False
    rArr = []
    thetaArr = []
    for testTAI in (tai, tai + DeltaT):
        ap, r, theta = coordConv.polarFromXY(x.getPos(testTAI), y.getPos(testTAI))
        rArr.append(r)
        thetaArr.append(theta)
        atPole = atPole or ap
    rPVT = coordConv.PVT()
    rPVT.pos = rArr[0]
    rPVT.vel = (rArr[1] - rArr[0]) / DeltaT
    rPVT.t = tai
    thetaPVT = coordConv.PVT()
    thetaPVT.pos = thetaArr[0]
    thetaPVT.vel = coordConv.wrapCtr(thetaArr[1] - thetaArr[0]) / DeltaT
    thetaPVT.t = tai
    return atPole, rPVT, thetaPVT
Example #7
0
def measureOrientationToErr():
    """Measure error in Coord.orientationTo for tiny offsets
    
    For best results modify Coord::orientationTo to not short-circuit tiny values of sinVal, cosVal
    """
    errDict = {}  # dict of distArcSec: (max orient error, max(sinVal, cosVal))
    for fromPolarAng in (-89, -72, -45.0, -30, 0.01, 12.5, 31, 47, 56, 68, 89):
        for fromEquatAng in (0, 41.0):  # should not matter
            fromCoord = coordConv.Coord(fromEquatAng, fromPolarAng)
            for fromOrient in (-90, -72, -45.0, -30, 0.01, 0, 12.5, 31, 45, 56,
                               68, 89):
                # offset by such small distances that toOrient=fromOrient
                # by 1e-6 the error is starting to go up, indicating that the approximation is failing
                for distArcSec in (5e-5, 1e-4, 2e-4, 3e-4, 4e-4, 5e-4, 1e-3,
                                   1e-2):
                    toCoord, dumToOrient = fromCoord.offset(
                        fromOrient, distArcSec / 3600)
                    toOrient = coordConv.wrapCtr(
                        180 + toCoord.orientationTo(fromCoord))

                    # expect fromOrient = toOrient
                    newErrArcSec = abs(toOrient - fromOrient) * 3600
                    oldErrArcSec = errDict.get(distArcSec, (0, 0))[0]
                    if newErrArcSec > oldErrArcSec:
                        toU = toCoord.getVecPos()
                        toU /= numpy.linalg.norm(toU)
                        fromU = fromCoord.getVecPos()
                        fromU /= numpy.linalg.norm(fromU)
                        sinVal = (toU[1] * fromU[0]) - (toU[0] * fromU[1])
                        cosVal = (toU[2] * ((fromU[0] * fromU[0]) + (fromU[1] * fromU[1]))) \
                                  - (fromU[2] * ((toU[0] * fromU[0]) + (toU[1] * fromU[1])))
                        errDict[distArcSec] = (newErrArcSec,
                                               max(sinVal, cosVal))
    distKeys = sorted(errDict.keys())
    print "Note that by 0.01 arcsec the error creeps up, indicating that the approximation toOrient=fromOrient is failing"
    for distArcSec in distKeys:
        errArcSec, maxSinCos = errDict[distArcSec]
        print "distArcSec=%0.3g arcsec, maxErr=%0.3g arcsec, maxSin/Cos=%0.3g" % (
            distArcSec, errArcSec, maxSinCos)