Commit fbea980c authored by Marco Buttu's avatar Marco Buttu
Browse files

Simulator completed: all the regression tests pass

parent bcd49f40
Loading
Loading
Loading
Loading
+92 −24
Original line number Original line Diff line number Diff line
from Receivers__POA import SRTKBandDerotator as POA
from __future__ import with_statement

import operator
import time
from multiprocessing import Process, Value, Lock
from Receivers__POA import SRTKBandDerotator
from Acspy.Servants.CharacteristicComponent import CharacteristicComponent as cc
from Acspy.Servants.CharacteristicComponent import CharacteristicComponent as cc
from Acspy.Servants.ContainerServices import ContainerServices as services
from Acspy.Servants.ContainerServices import ContainerServices as services
from Acspy.Servants.ComponentLifecycle import ComponentLifecycle as lcycle
from Acspy.Servants.ComponentLifecycle import ComponentLifecycle as lcycle
from Acspy.Common.TimeHelper import getTimeStamp
from Acspy.Util.BaciHelper import addProperty
from Acspy.Util.BaciHelper import addProperty
from DerotatorSimulator.devios import GenericDevIO
from DerotatorSimulator.devios import GenericDevIO


@@ -9,21 +15,20 @@ from DerotatorSimulator.devios import GenericDevIO
__copyright__ = "Marco Buttu <mbuttu@oa-cagliari.inaf.it>"
__copyright__ = "Marco Buttu <mbuttu@oa-cagliari.inaf.it>"




class DerotatorSimulatorImpl(POA, cc, services, lcycle):
class DerotatorSimulatorImpl(SRTKBandDerotator, cc, services, lcycle):
 
 
    def __init__(self):
    def __init__(self):
        cc.__init__(self)
        services.__init__(self)
        services.__init__(self)
        self._setDefault()
        self._setDefault()


    def initialize(self):
    def initialize(self):
        addProperty(self, 'actPosition', devio_ref=GenericDevIO()) 
        addProperty(self, 'cmdPosition', devio_ref=GenericDevIO()) 
        addProperty(self, 'enginePosition', devio_ref=GenericDevIO()) 
        addProperty(self, 'enginePosition', devio_ref=GenericDevIO()) 
        # addProperty(self, 'actPosition', devio_ref=GenericDevIO())
        addProperty(self, 'positionDiff', devio_ref=GenericDevIO()) 
        # addProperty(self, 'cmdPosition', devio_ref=GenericDevIO())
        addProperty(self, 'tracking', devio_ref=GenericDevIO()) 
        # addProperty(self, 'positionDiff', devio_ref=GenericDevIO())
        addProperty(self, 'status', devio_ref=GenericDevIO()) 
        # addProperty(self, 'tracking', devio_ref=GenericDevIO())
        addProperty(self, 'icd_verbose_status', devio_ref=GenericDevIO()) 
        # addProperty(self, 'icd_verbose_status', devio_ref=GenericDevIO())
        # addProperty(self, 'status', devio_ref=GenericDevIO())


    def cleanUp(self):
    def cleanUp(self):
        pass
        pass
@@ -32,20 +37,20 @@ class DerotatorSimulatorImpl(POA, cc, services, lcycle):
        return 'DerotatorSimulator'
        return 'DerotatorSimulator'


    def setup(self):
    def setup(self):
        self.is_ready = True
        self.status.is_ready.value = True
        self.is_tracking = True
        self.status.is_tracking.value = True


    def isReady(self):
    def isReady(self):
        return self.is_ready
        return self.status.is_ready.value


    def isSlewing(self):
    def isSlewing(self):
        return self.is_slewing
        return self.status.is_slewing.value


    def isTracking(self):
    def isTracking(self):
        return self.is_tracking
        return self.status.is_tracking.value


    def isUpdating(self):
    def isUpdating(self):
        return self.is_updating
        return self.status.is_updating.value


    def powerOff(self):
    def powerOff(self):
        pass
        pass
@@ -61,14 +66,17 @@ class DerotatorSimulatorImpl(POA, cc, services, lcycle):


    def setPosition(self, position):
    def setPosition(self, position):
        self.cmd_position = position
        self.cmd_position = position
        p = Process(target=DerotatorSimulatorImpl._set_position_process, 
                    args=(self.status, position, self.getSpeed()))
        p.start()
        if self.getMinLimit() < position < self.getMaxLimit():
        if self.getMinLimit() < position < self.getMaxLimit():
            self.position = position
            self.history.insert(position)


    def getActPosition(self):
    def getActPosition(self):
        return self.position
        return self.history.get()


    def getPositionFromHistory(self, t):
    def getPositionFromHistory(self, t):
         return self.position # TODO
         return self.history.get(t)


    def getCmdPosition(self):
    def getCmdPosition(self):
        return self.cmd_position
        return self.cmd_position
@@ -83,10 +91,70 @@ class DerotatorSimulatorImpl(POA, cc, services, lcycle):
        self._setDefault()
        self._setDefault()


    def _setDefault(self):
    def _setDefault(self):
        self.position = self.cmd_position = 0.0
        self.history = History()
        self.cmd_position = self.history.get()
        self.speed = 3 
        self.speed = 3 
        self.is_ready = False
        self.status = Status()
        self.is_tracking = False

        self.is_updating = False
    @staticmethod
        self.is_slewing = False
    def _set_position_process(status, position, speed):
        status.is_slewing.value = True
        time.sleep(position/speed*1.0) # Speed degrees per second
        status.is_slewing.value = False


class History(object):
    lock = Lock()

    def __init__(self):
        self.history = []
        self.insert(0)

    def insert(self, position):
        data = (getTimeStamp().value, position)
        with History.lock:
            self.history.append(data)
            self.history.sort(key=operator.itemgetter(0))
            self.history = self.history[-2**15:] # Last 2**15 positions

    def clean(self, since=0):
        target_time = since if since else getTimeStamp().value
        with History.lock:
            idx = len(self.history)
            self.history.sort(key=operator.itemgetter(0))
            for idx, item in enumerate(self.history):
                timestamp = item[0]
                if timestamp > target_time:
                    break
            self.history = self.history[:idx] 

    def get(self, target_time=None):
        """Return the position @target_time"""
        if not target_time:
            target_time = getTimeStamp().value
        size = len(self.history)
        idx = -1
        with History.lock:
            while idx >= -size:
                data = self.history[idx]
                timestamp, position = data[0], data[1:]
                if timestamp <= target_time:
                    return data[-1]
                elif idx - 1 > -size:
                    prev_timestamp = self.history[idx - 1]
                    if prev_timestamp <= target_time:
                        return self.history[idx - 1][-1] # It's better to interpolate
                    else:
                        idx -= 1
                        continue
                else:
                    return self.history[-size][-1]
                    

class Status(object):
    def __init__(self):
        self.is_slewing = Value('i', 0)
        self.is_ready = Value('i', 0)
        self.is_tracking = Value('i', 0)
        self.is_updating = Value('i', 0)
+1 −1
Original line number Original line Diff line number Diff line
@@ -8,7 +8,7 @@
    xmlns:cdb="urn:schemas-cosylab-com:CDB:1.0"
    xmlns:cdb="urn:schemas-cosylab-com:CDB:1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              
              
    Name="DerotatorSimulator"    
    Name="SRTKBandDerotator"    
    Code="DerotatorSimulator.DerotatorSimulatorImpl"
    Code="DerotatorSimulator.DerotatorSimulatorImpl"
    Type="IDL:alma/Receivers/SRTKBandDerotator:1.0"
    Type="IDL:alma/Receivers/SRTKBandDerotator:1.0"
    ImplLang="py"
    ImplLang="py"