source: trunk/model/shooting.py @ 395

Revision 395, 9.0 KB checked in by fma, 5 years ago (diff)

Moved mosaic params to Mosaic object

  • Property svn:keywords set to Id
Line 
1# -*- coding: iso-8859-1 -*-
2
3""" Panohead remote control.
4
5License
6=======
7
8 - B{papywizard} (U{http://trac.gbiloba.org/papywizard}) is Copyright:
9  - (C) 2007-2008 Frédéric Mantegazza
10
11This software is governed by the B{CeCILL} license under French law and
12abiding by the rules of distribution of free software.  You can  use,
13modify and/or redistribute the software under the terms of the CeCILL
14license as circulated by CEA, CNRS and INRIA at the following URL
15U{http://www.cecill.info}.
16
17As a counterpart to the access to the source code and  rights to copy,
18modify and redistribute granted by the license, users are provided only
19with a limited warranty  and the software's author,  the holder of the
20economic rights,  and the successive licensors  have only  limited
21liability.
22
23In this respect, the user's attention is drawn to the risks associated
24with loading,  using,  modifying and/or developing or reproducing the
25software by the user in light of its specific status of free software,
26that may mean  that it is complicated to manipulate,  and  that  also
27therefore means  that it is reserved for developers  and  experienced
28professionals having in-depth computer knowledge. Users are therefore
29encouraged to load and test the software's suitability as regards their
30requirements in conditions enabling the security of their systems and/or
31data to be ensured and,  more generally, to use and operate it in the
32same conditions as regards security.
33
34The fact that you are presently reading this means that you have had
35knowledge of the CeCILL license and that you accept its terms.
36
37Module purpose
38==============
39
40Model
41
42Implements
43==========
44
45- Shooting
46
47@author: Frédéric Mantegazza
48@copyright: (C) 2007-2008 Frédéric Mantegazza
49@license: CeCILL
50"""
51
52__revision__ = "$Id$"
53
54import time
55
56from papywizard.common.loggingServices import Logger
57from papywizard.common.signal import Signal
58from papywizard.common.configManager import ConfigManager
59from papywizard.common.exception import HardwareError
60from papywizard.common.data import Data
61from papywizard.model.camera import Camera
62from papywizard.model.mosaic import Mosaic
63
64
65class Shooting(object):
66    """ Shooting model.
67    """
68    def __init__(self, realHardware, simulatedHardware):
69        """ Init the object.
70
71        @param realHardware: real hardware head
72        @type realHardware: {Head}
73
74        @param simulatedHardware: simulated hardware head
75        @type simulatedHardware: {HeadSimulation}
76        """
77        self.__shooting = False
78        self.__suspend = False
79        self.__stop = False
80        self.__setParams = None
81        self.__manualShoot = False
82
83        self.realHardware = realHardware
84        self.simulatedHardware = simulatedHardware
85        self.hardware = self.simulatedHardware
86        self.switchToRealHardwareSignal = Signal()
87        self.newPictSignal = Signal()
88        self.camera = Camera()
89        self.mosaic = Mosaic(self.camera)
90        #self.fullSpherical = FullSpherical()
91
92        self.position = self.hardware.readPosition()
93        self.progress = 0.
94        self.sequence = "Idle"
95
96    # Properties
97    def __getStabilizationDelay(self):
98        """
99        """
100        return ConfigManager().getFloat('Preferences', 'SHOOTING_STABILIZATION_DELAY')
101   
102    def __setStabilizationDelay(self, stabilizationDelay):
103        """
104        """
105        ConfigManager().setFloat('Preferences', 'SHOOTING_STABILIZATION_DELAY', stabilizationDelay, 1)
106   
107    stabilizationDelay = property(__getStabilizationDelay, __setStabilizationDelay)
108
109    def switchToRealHardware(self):
110        """ Use real hardware.
111        """
112        try:
113            #self.simulatedHardware.shutdown()
114            self.realHardware.init()
115            Logger().debug("Shooting.switchToRealHardware(): realHardware initialized")
116            self.position = self.realHardware.readPosition()
117            self.hardware = self.realHardware
118            self.switchToRealHardwareSignal.emit(True)
119        except HardwareError, message:
120            Logger().exception("Shooting.switchToRealHardware()") 
121            self.switchToRealHardwareSignal.emit(False, str(message))
122
123    def switchToSimulatedHardware(self):
124        """ Use simulated hardware.
125        """
126        self.realHardware.shutdown()
127        self.hardware = self.simulatedHardware
128        self.hardware.init()
129        self.position = self.hardware.readPosition()
130
131    def setManualShoot(self, flag):
132        """ Turn on/off manual shoot.
133
134        In manual shoot mode, the head switch to suspend at each end of position.
135
136        @param flag: flag for manual shoot
137        @type flag: bool
138        """
139        self.__manualShoot = flag
140
141    def initProgress(self):
142        """ Init progress value.
143        """
144        self.progress = 0.
145        self.sequence = "Idle" # find better
146
147    def start(self):
148        """ Start pano shooting.
149        """
150        def checkSuspendStop():
151            """ Check if suspend or stop requested.
152            """
153            if self.__suspend:
154                Logger().info("Suspend")
155                self.sequence = "Idle"
156                while self.__suspend:
157                    time.sleep(0.1)
158                Logger().info("Resume")
159            if self.__stop:
160                Logger().info("Stop")
161                raise StopIteration
162
163        Logger().trace("Shooting.start()")
164
165        data = Data()
166        values = {'stabilizationDelay': "%.1f" % self.stabilizationDelay,
167                  'overlap': "%.2f" % self.mosaic.overlap,
168                  'yawRealOverlap': "%.2f" % self.mosaic.yawRealOverlap,
169                  'pitchRealOverlap': "%.2f" % self.mosaic.pitchRealOverlap,
170                  'cameraOrientation': "%s" % self.mosaic.cameraOrientation,
171                  'timeValue': "%.1f" % self.camera.timeValue,
172                  'nbPicts': "%d" % self.camera.nbPicts,
173                  'sensorCoef': "%.1f" % self.camera.sensorCoef,
174                  'sensorRatio': "%s" % self.camera.sensorRatio,
175                  'focal': "%.1f" % self.camera.lens.focal,
176                  'fisheye': "%s" % self.camera.lens.fisheye,
177                  'template': "mosaic",
178                  'yawNbPicts': "%d" % self.mosaic.yawNbPicts,
179                  'pitchNbPicts': "%d" % self.mosaic.pitchNbPicts
180              }
181        data.createHeader(values)
182        self.progress = 0.
183        self.__stop = False
184        self.__shooting = True
185
186        # Loop over all positions
187        try:
188            for i, (yaw, pitch) in enumerate(self.mosaic):
189                Logger().debug("Shooting.start(): Goto yaw=%.1f pitch=%.1f" % (yaw, pitch))
190                Logger().info("Moving")
191                self.sequence = "Moving"
192                self.hardware.gotoPosition(yaw, pitch)
193
194                checkSuspendStop()
195
196                Logger().info("Stabilization")
197                self.sequence = "Stabilizing"
198                time.sleep(self.stabilizationDelay)
199
200                if self.__manualShoot:
201                    self.__suspend = True
202                    Logger().info("Manual shoot")
203
204                checkSuspendStop()
205
206                Logger().info("Shooting")
207                for pict in xrange(self.camera.nbPicts):
208                    Logger().debug("Shooting.start(): Shooting %d/%d" % (pict + 1, self.camera.nbPicts))
209                    self.sequence = "Shooting %d/%d" % (pict + 1, self.camera.nbPicts)
210                    self.hardware.shoot(self.camera.timeValue)
211                    data.addPicture(pict + 1, yaw, pitch)
212
213                    checkSuspendStop()
214
215                progressFraction = float((i + 1)) / float(self.mosaic.totalNbPicts)
216                self.progress = progressFraction
217                self.newPictSignal.emit(yaw, pitch) # Include progress?
218
219            Logger().debug("Shooting.start(): finished")
220
221        except StopIteration:
222            Logger().debug("Shooting.start(): Stop detected")
223            self.sequence = "Canceled"
224        else:
225            self.sequence = "Over"
226           
227        self.__shooting = False
228
229    def isShooting(self):
230        """ Test if shooting is running.
231
232        @return: True if shooting is running, False otherwise
233        @rtype: bool
234        """
235        return self.__shooting
236
237    def suspend(self):
238        """ Suspend execution of pano shooting.
239        """
240        Logger().trace("Shooting.suspend()")
241        self.__suspend = True
242
243    def isSuspended(self):
244        """ Test if shotting is suspended.
245
246        @return: True if shooting is suspended, False otherwise
247        @rtype: bool
248        """
249        return self.__suspend
250
251    def resume(self):
252        """ Resume  execution of shooting.
253        """
254        Logger().trace("Shooting.resume()")
255        self.__suspend = False
256
257    def stop(self):
258        """ Cancel execution of shooting.
259        """
260        Logger().trace("Shooting.stop()")
261        self.__stop = True
262        self.__suspend = False
263        self.hardware.stopAxis()
264
265    def shutdown(self):
266        """ Cleanly terminate the model.
267
268        Save values to preferences.
269        """
270        Logger().trace("Shooting.shutdown()")
271        self.realHardware.shutdown()
272        self.simulatedHardware.shutdown()
273        self.camera.shutdown()
Note: See TracBrowser for help on using the repository browser.