You are not logged in.

> The forum rules have been updated. Please take a moment to read them.


#51 2010-05-25 12:49:03

lemon
Member
Registered: 2010-05-04
Posts: 17

Re: Merlin does not center correctly when taking shots

Ok, I've tried with alternate drive disabled, and it looks much better now!


Uploaded Images

Offline

 

#52 2010-05-25 12:49:21

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Andrew, try with both versions. No specific params needed in the plugins.


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#53 2010-05-25 18:38:02

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Andrew, try with both versions. No specific params needed in the plugins.

Frederic,

Here are the image sets with XML files. One set shot with PW 2.1.17 and the other with PW 2.1.19, from N800 tablets.

10x10 mosaic set as Nb.. picts, 1496x2256 pixel images, focal length set at 70mm, resulting in yaw separation of approx. 10 degrees.

I'll let you report what you see, and what you think it tells us.

PW 2.1.17 image set (78MB ZIP):
http://www.three60views.org.uk/papywiza … mm-alt.zip

PW 2.1.19 image set (87MB ZIP):
http://www.three60views.org.uk/papywiza … mm-alt.zip

Last edited by mediavets (2010-05-25 18:38:42)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#54 2010-05-26 18:10:25

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Tell me if I am wrong, but it seems there is no shift in these panos... And there is no major difference between the 2 panos (without the optimization, we get exactly the same little errors).


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#55 2010-05-26 18:10:44

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

Frederic,

Looking forward to your analysis and feedback.


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#56 2010-05-26 19:35:23

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

I just made a new test, with my N800, Papywizard 2.1.19, with the same firmware as yours (010981), and I don't see real shift. I have some positionning errors (0.5°), but no shit. I tried with and without alternate move: it does not make a big difference (maybe a better accuracy without alternate drive)...


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#57 2010-05-26 20:05:51

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

I just made a new test, with my N800, Papywizard 2.1.19, with the same firmware as yours (010981), and I don't see real shift. I have some positionning errors (0.5°), but no shit. I tried with and without alternate move: it does not make a big difference (maybe a better accuracy without alternate drive)...

If you don't see the shift why does everyone else?

What focal length setting did you use? If it's less than about 125mm with a cropped sensor (approx 200mm equiv on fullframe) - or a yaw separation of greater than 6-7 degrees - then I would not expect to see the shift.

Last edited by mediavets (2010-05-26 20:30:37)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#58 2010-05-26 20:12:34

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Tell me if I am wrong, but it seems there is no shift in these panos... And there is no major difference between the 2 panos (without the optimization, we get exactly the same little errors).

Yes, I agree, there is no shift and no real difference bwteen them. And that is what I would have predicted.

And I believe that there is no shift because the yaw separation at approx. 10 degrees, is greater than that at which the alternate drive kicks in I think.

My tests and observations suggest that the shifting anomaly is only shown when the yaw separation is less than approx. 6-7 degrees and the alternative drive is in use. Does that match you experience and make sense to you?


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#59 2010-05-26 20:39:20

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

I used a 200mm for my tests.

Yes, the problem seems to occur when the head stays at very low speed (move < 6°). And it is worse with alternate drive enable, because the final 'goto' move is shorter...


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#60 2010-05-26 22:22:12

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

I used a 200mm for my tests.

Yes, the problem seems to occur when the head stays at very low speed (move < 6°). And it is worse with alternate drive enable, because the final 'goto' move is shorter...

Frederic,

Do you have theory of why this happens? Is this some sort of inherent characteristic of the electro-mechanical mechanism of the Merlin head or is it something that can be overcome via modifications to the software?

If it cannot be overcome, the other than disabling the alternate drive altogether (which appesr to overcome the problme but also seems to increase shooting time by about 50%), is there any set of recommendations you could make about what settings to use for the alternate drive in different setups to minimise the issue?

Last edited by mediavets (2010-05-26 23:37:15)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#61 2010-05-26 23:18:06

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

I have to admit that I have no idea how to fix that problem... Maybe you can try to increase the inertia angle (up to 2°), to be sure the head do not over-shoot during the alternate move.


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#62 2010-05-27 10:39:46

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

I have to admit that I have no idea how to fix that problem... Maybe you can try to increase the inertia angle (up to 2°), to be sure the head do not over-shoot during the alternate move.

I tried with the Inertia angle set to 3 degrees, it made no discernible difference except to make the shoot time a little longer.

Focal length set at 150mm. Camera is a Nikon D40 1.5x crop sensor with Nikkor 50mm lens.

I am comparing with two other test image sets made earlier using in one case an Intertia angle of 1 degree (the default) and in the second case with the Alternate drive turned off.

Screenshot 1 - shows initial import results.
Screenshot 2 - shows results using an Interia angle of 3 degrees.
Screenshot 3 - shows results using an Inertia angle of 1 degree.
Screenshot 4- show the results with the Alternate drive turned off.


Uploaded Images

Last edited by mediavets (2010-05-27 10:41:40)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#63 2010-05-27 13:25:20

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Could some other Merlin users try to make similar tests?


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#64 2010-05-28 00:31:29

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Could some other Merlin users try to make similar tests?

Seems there are no takers...

Anyway I repeated the tests on my second Merlin head which also has firmware 010981.

The results are almost identical.

10x10 mosaics, focal lenght set at 150mm, PW 2.1.19-1 on N800, APG 2.0.8 on Windows XP 32-bit using the Papywizard Import filter.

Screenshot 1 - shows initial import results.
Screenshot 2 - shows results using an Inertia angle of 1 degree.
Screenshot 3 - shows results using an Inertia angle of 3 degrees.
Screenshot 4- show the results with the Alternate drive turned off.


Uploaded Images


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#65 2010-05-28 07:34:21

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Could you try this Merlin/Orion plugin version:

Code:

# -*- coding: utf-8 -*-

""" Panohead remote control.

License
=======

 - B{Papywizard} (U{http://www.papywizard.org}) is Copyright:
  - (C) 2007-2010 Frédéric Mantegazza

This software is governed by the B{CeCILL} license under French law and
abiding by the rules of distribution of free software.  You can  use,
modify and/or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
U{http://www.cecill.info}.

As a counterpart to the access to the source code and  rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty  and the software's author,  the holder of the
economic rights,  and the successive licensors  have only  limited
liability.

In this respect, the user's attention is drawn to the risks associated
with loading,  using,  modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean  that it is complicated to manipulate,  and  that  also
therefore means  that it is reserved for developers  and  experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and,  more generally, to use and operate it in the
same conditions as regards security.

The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.

Module purpose
==============

Hardware

Implements
==========

 - MerlinOrionAxis
 - MerlinOrionAxisController
 - MerlinOrionShutter
 - MerlinOrionShutterController

@author: Frédéric Mantegazza
@copyright: (C) 2007-2010 Frédéric Mantegazza
@license: CeCILL
@todo: add private methods to MerlinOrionHardware for sending commands to MerlinOrion
"""

__revision__ = "$Id: merlinOrionPlugins.py 2430 2010-05-23 20:27:22Z fma $"

import time
import threading

from PyQt4 import QtCore, QtGui

from papywizard.common import config
from papywizard.common.configManager import ConfigManager
from papywizard.common.loggingServices import Logger
from papywizard.hardware.merlinOrionHardware import MerlinOrionHardware
from papywizard.plugins.pluginsManager  import PluginsManager
from papywizard.plugins.abstractAxisPlugin import AbstractAxisPlugin
from papywizard.plugins.shutterPlugin import ShutterPlugin
from papywizard.plugins.abstractHardwarePlugin import AbstractHardwarePlugin
from papywizard.plugins.axisPluginController import AxisPluginController
from papywizard.plugins.hardwarePluginController import HardwarePluginController
from papywizard.plugins.shutterPluginController import ShutterPluginController
from papywizard.view.pluginFields import SpinBoxField, DoubleSpinBoxField, CheckBoxField

NAME = "Merlin-Orion"

DEFAULT_ALTERNATE_DRIVE = True
DEFAULT_ALTERNATE_DRIVE_ANGLE = 7. # °
DEFAULT_INERTIA_ANGLE = 1. # °

TAB_HARD = unicode(QtGui.QApplication.translate("merlinOrionPlugins", 'Hard'))
LABEL_ALTERNATE_DRIVE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Alternate drive"))
LABEL_ALTERNATE_DRIVE_ANGLE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Alternate drive angle"))
LABEL_INERTIA_ANGLE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Inertia angle"))

AXIS_ACCURACY = 0.1 # °
AXIS_TABLE = {'yawAxis': 1,
              'pitchAxis': 2,
              'shutter': 1
              }
MANUAL_SPEED_TABLE = {'slow': 170,  # "AA0000"  / 5
                      'alternate': 80, # "500000"
                      'normal': 34, # "220000" nominal
                      'fast': 17   # "110000"  * 2
                      }


class MerlinOrionAxis(AbstractHardwarePlugin, AbstractAxisPlugin, QtCore.QThread):
    """
    """
    def __init__(self, *args, **kwargs):
        AbstractHardwarePlugin.__init__(self, *args, **kwargs)  # Only 1?
        AbstractAxisPlugin.__init__(self, *args, **kwargs)
        QtCore.QThread.__init__(self)

    def _init(self):
        Logger().trace("MerlinOrionAxis._init()")
        AbstractHardwarePlugin._init(self)
        AbstractAxisPlugin._init(self)
        self._hardware = MerlinOrionHardware()
        self.__run = False
        self.__driveFlag = False
        self.__setPoint = None

    def _defineConfig(self):
        AbstractAxisPlugin._defineConfig(self)
        AbstractHardwarePlugin._defineConfig(self)
        self._addConfigKey('_alternateDrive', 'ALTERNATE_DRIVE', default=DEFAULT_ALTERNATE_DRIVE)
        self._addConfigKey('_alternateDrive', 'ALTERNATE_DRIVE_ANGLE', default=DEFAULT_ALTERNATE_DRIVE_ANGLE)
        self._addConfigKey('_inertiaAngle', 'INERTIA_ANGLE', default=DEFAULT_INERTIA_ANGLE)

    def activate(self):
        Logger().trace("MerlinOrionHardware.activate()")
        AbstractAxisPlugin.activate(self)

        # Start the thread
        self.start()

    def deactivate(self):
        Logger().trace("MerlinOrionHardware.deactivate()")

        # Stop the thread
        self._stopThread()
        self.wait()
        AbstractAxisPlugin.deactivate(self)

    def init(self):
        Logger().trace("MerlinOrionAxis.init()")
        self._hardware.setAxis(AXIS_TABLE[self.capacity]),
        AbstractHardwarePlugin.init(self)

    def shutdown(self):
        Logger().trace("MerlinOrionAxis.shutdown()")
        self.stop()
        AbstractHardwarePlugin.shutdown(self)
        AbstractAxisPlugin.shutdown(self)

    def run(self):
        """ Main entry of the thread.
        """
        threadName = "%s_%s" % (self.name, self.capacity)
        threading.currentThread().setName(threadName)
        Logger().debug("MerlinOrionAxis.run(): start thread")
        self.__run = True
        while self.__run:
            if self.__driveFlag:

                # Choose alternate drive if needed
                currentPos = self.read()
                if self._config['ALTERNATE_DRIVE'] and \
                   1.1 * self._config['INERTIA_ANGLE'] < abs(self.__setPoint - currentPos) < self._config['ALTERNATE_DRIVE_ANGLE']:
                    self._alternateDrive(self.__setPoint)
                else:
                    self._directDrive(self.__setPoint)
                self.__driveFlag = False
                self.waitEndOfDrive()

            self.msleep(config.SPY_REFRESH_DELAY)

        Logger().debug("MerlinOrionAxis.run(): thread terminated")

    def _stopThread(self):
        """ Stop the thread.
        """
        self.__run = False

    def read(self):
        pos = self._hardware.read() - self._offset
        return pos

    def drive(self, pos, useOffset=True, wait=True):
        Logger().debug("MerlinOrionAxis.drive(): '%s' drive to %.1f" % (self.capacity, pos))
        currentPos = self.read()

        self._checkLimits(pos)

        # Only move if needed
        if abs(pos - currentPos) > AXIS_ACCURACY or not useOffset:
            if not useOffset:
                pos -= self._offset

            self.__setPoint = pos
            self.__driveFlag = True # Start thread action

            # Wait end of movement
            if wait:
                self.waitEndOfDrive()

    def _directDrive(self, pos):
        """ Default (hardware) drive.

        @param pos: position to reach, in °
        @type pos: float
        """
        Logger().trace("MerlinOrionAxis._directDrive()")
        pos += self._offset
        self._hardware.drive(pos)

    def _alternateDrive(self, pos):
        """ Alternate drive.

        This method implements an external closed-loop regulation.
        It is faster for angles < 6-7°, because in this case, the
        head does not accelerate to full speed, but rather stays at
        very low speed.

        @param pos: position to reach, in °
        @type pos: float
        """
        Logger().trace("MerlinOrionAxis._alternateDrive()")

        # Compute initial direction
        currentPos = self.read()
        if pos > currentPos:
            dir_ = '+'
        else:
            dir_ = '-'
        stopRequest = False

        # Alternate speed move
        Logger().debug("MerlinOrionAxis._alternateDrive(): alternate speed move")
        self._hardware.startJog(dir_, MANUAL_SPEED_TABLE['alternate'])

        # Check when stop
        while (dir_ == '-' and self.read() - pos > self._config['INERTIA_ANGLE']) or \
              (dir_ == '+' and pos - self.read() > self._config['INERTIA_ANGLE']):

            # Test if a stop request has been sent
            if not self.isMoving():
                stopRequest = True
                break
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        self._hardware.stop()

        # Final move
        if not stopRequest:
            Logger().debug("MerlinOrionAxis._alternateDrive(): final move")
            pos += self._offset
            self._hardware.drive(pos)

    def waitEndOfDrive(self):
        while self.isMoving():
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        self.waitStop()

    def startJog(self, dir_):
        self._hardware.startJog(dir_, MANUAL_SPEED_TABLE[self._manualSpeed])

    def stop(self):
        self.__driveFlag = False
        self._hardware.stop()
        self.waitStop()

    def waitStop(self):
        pos = self.read()
        time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        while True:
            if abs(pos - self.read()) <= AXIS_ACCURACY:
                break
            pos = self.read()
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)

    def isMoving(self):
        status = self._hardware.getStatus()
        if status[1] != '0' or self.__driveFlag:
            return True
        else:
            return False


class MerlinOrionAxisController(AxisPluginController, HardwarePluginController):
    def _defineGui(self):
        AxisPluginController._defineGui(self)
        HardwarePluginController._defineGui(self)
        self._addTab('Hard', TAB_HARD)
        self._addWidget('Hard', LABEL_ALTERNATE_DRIVE, CheckBoxField, (), 'ALTERNATE_DRIVE')
        self._addWidget('Hard', LABEL_ALTERNATE_DRIVE_ANGLE, SpinBoxField, (3, 15, "", u" °"), 'ALTERNATE_DRIVE_ANGLE')
        self._addWidget('Hard', LABEL_INERTIA_ANGLE, DoubleSpinBoxField, (0.1, 9.9, 1, .1, "", u" °"), 'INERTIA_ANGLE')


class MerlinOrionShutter(AbstractHardwarePlugin, ShutterPlugin):
    def __init__(self, *args, **kwargs):
        """
        """
        AbstractHardwarePlugin.__init__(self, *args, **kwargs)
        ShutterPlugin.__init__(self, *args, **kwargs)

    def _init(self):
        Logger().trace("MerlinOrionShutter._init()")
        AbstractHardwarePlugin._init(self)
        ShutterPlugin._init(self)
        self._hardware = MerlinOrionHardware()

    def _defineConfig(self):
        AbstractHardwarePlugin._defineConfig(self)
        ShutterPlugin._defineConfig(self)

    def _triggerOnShutter(self):
        """ Set the shutter on.
        """
        self._hardware.setOutput(True)

    def _triggerOffShutter(self):
        """ Set the shutter off.
        """
        self._hardware.setOutput(False)

    def init(self):  # Move to AbstractHardwarePlugin?
        Logger().trace("MerlinOrionShutter.init()")
        self._hardware.setAxis(AXIS_TABLE[self.capacity]),
        AbstractHardwarePlugin.init(self)

    def shutdown(self):
        Logger().trace("MerlinOrionShutter.shutdown()")
        self._triggerOffShutter()
        AbstractHardwarePlugin.shutdown(self)
        ShutterPlugin.shutdown(self)


class MerlinOrionShutterController(ShutterPluginController, HardwarePluginController):
    def _defineGui(self):
        ShutterPluginController._defineGui(self)
        HardwarePluginController._defineGui(self)


def register():
    """ Register plugins.
    """
    PluginsManager().register(MerlinOrionAxis, MerlinOrionAxisController, capacity='yawAxis', name=NAME)
    PluginsManager().register(MerlinOrionAxis, MerlinOrionAxisController, capacity='pitchAxis', name=NAME)
    PluginsManager().register(MerlinOrionShutter, MerlinOrionShutterController, capacity='shutter', name=NAME)

Just put it in the user plugins dir, restart Papywizard, and select this vesion (should appear with a number)...


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#66 2010-05-28 09:18:53

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Could you try this Merlin/Orion plugin version:
.............
Just put it in the user plugins dir, restart Papywizard, and select this vesion (should appear with a number)...

How do I get it into this directory, and what filename should I give it, on a Nokia N800, please?


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#67 2010-05-28 10:07:09

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

On Nokia, the dir is:

/home/user/.config/papywizard2/plugins/

you will have to use 'cd' command to move it from the card to this dir.

You can use the name you want for the file, as long as it ends with .py. The original plugin is named merlinOrionPlugins.py.


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#68 2010-05-28 12:47:49

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

On Nokia, the dir is:

/home/user/.config/papywizard2/plugins/

you will have to use 'cd' command to move it from the card to this dir.

You can use the name you want for the file, as long as it ends with .py. The original plugin is named merlinOrionPlugins.py.

I'm a complete idiot when it comes to Linux/Maemo commandline operations.

If my card is /media/mmc2 and I name the file merlinOrionPlugins-2.py then what would the comand be to copy the file from the card to the desired destination?
................

I had a look at doing it on Windows XP and it seems that the correct directory/folder there would be

C:\Program Files\Papywizard\Library\papywizard\plugins

Is that correct?

If so then I se that all the files in that directrory/folder seem to have the filename extension .pyo

Is it .py on Maemo and .pyo on Windows?

Anyway I put your code in a file named merlinorionplugin2.pyo is that directory/folder but I don't see an extra pluin option for Yaw or Pitch in Papywizard.

Should it work in Windows XP as well as on Maemo?


Uploaded Images

Last edited by mediavets (2010-05-28 12:49:18)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#69 2010-05-28 16:06:05

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

The correct dir under windows is:

C:\Documents and settings\<user>\Application Data\papywizard2\plugins\

(you need to un-hide the system files in the explorer configuration).

Use the .py extension, not .pyo.

Under maemo, use the following command:

$ cp /media/mmc2/merlinOrionPlugins-2.py /home/user/.config/papywizard2/plugins/


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#70 2010-05-28 16:28:23

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

The correct dir under windows is:

C:\Documents and settings\<user>\Application Data\papywizard2\plugins\

(you need to un-hide the system files in the explorer configuration).

Use the .py extension, not .pyo.

OK - so I placed your code in a suitably named file in that location, and...
Papywizard now fails to load witb this error:

Traceback (most recent call last):
  File "main.py", line 186, in main
  File "papywizard\plugins\pluginsManager.pyo", line 94, in load
  File "papywizard\plugins\pluginsManager.pyo", line 111, in parseDir
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb0 in position 0: unexpected code byte

What have I done wrong?
.........
Update:

Same problem on Nokia too.
.........

Have I somehow screwed up your code in getting it from your forum post into a file?


Uploaded Images

Last edited by mediavets (2010-05-28 16:42:34)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#71 2010-05-28 17:20:59

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Be sure to save the code with the utf-8 encoding. What editor did you use? If you can't find how to do that, remove all special chars (éèçà°...) from the code.


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#72 2010-05-28 17:26:33

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Be sure to save the code with the utf-8 encoding. What editor did you use? If you can't find how to do that, remove all special chars (éèçà°...) from the code.

I used Wordpad and saved as text.

If that's no good, and sems it's not, maybe you could email the code file to me as an attachemnet (andrews@mediavets.co.uk).


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#73 2010-05-28 17:41:01

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Try saving the file using 'Unicode document text' type...


Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

#74 2010-05-28 18:41:14

mediavets
Moderator
From: Isleham, Cambridgeshire, UK.
Registered: 2007-11-14
Posts: 9825
Website

Re: Merlin does not center correctly when taking shots

fma38 wrote:

Try saving the file using 'Unicode document text' type...

Tried with Windows XP and now I get a different Unhandled exception error message:

'Traceback (most recent call last):
  File "main.py", line 186, in main
  File "papywizard\plugins\pluginsManager.pyo", line 94, in load
  File "papywizard\plugins\pluginsManager.pyo", line 111, in parseDir
  File "C:\Documents and Settings\Administrator\Application Data\papywizard2\plugins\merlinorionplugins-2.py", line 1
SyntaxError: Non-ASCII character '\xff' in file C:\Documents and Settings\Administrator\Application Data\papywizard2\plugins\merlinorionplugins-2.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details (merlinorionplugins-2.py, line 1)'

What is it complaining about?
..............
Anyway - moving on, I tried using Notepad which, unlike Wordpad, offers a UTF-8 encoding option so I chose that.

Now I get another different Unhandled exception error message:

'Traceback (most recent call last):
  File "main.py", line 186, in main
  File "papywizard\plugins\pluginsManager.pyo", line 94, in load
  File "papywizard\plugins\pluginsManager.pyo", line 111, in parseDir
  File "C:\Documents and Settings\Administrator\Application Data\papywizard2\plugins\merlinorionplugins-3.py", line 69, in <module>
ImportError: No module named shutterPlugin'

Any ideas?

Last edited by mediavets (2010-05-28 18:49:08)


Andrew Stephens
Nikon D40, Nikkor 10.5mm fisheye, Sigma 8mm f3.5 fisheye, Nikkor 18-55/50/35mm lenses, Nodal Ninja 5 Lite, Nodal Ninja 4 with R-D16, Agno's MrotatorTCS short.
Nikon P5100, CP5000, CP995, FC-E8, WC-E63,WC-E68, TC-E2, Kaidan Kiwi 995, Bophoto pano bracket, Agno's MrotatorA.
Merlin/Orion robotic pano head + Papywizard on Nokia 770/N800/N810 and Windows 8/XP/2K.

Offline

 

#75 2010-05-28 21:28:15

fma38
Moderator
From: Grenoble, France
Registered: 2005-12-07
Posts: 6181
Website

Re: Merlin does not center correctly when taking shots

Oups, Unicode type is not utf-8...

Could someone suggest a good code editor for windows (something lighter than eclipse, please)?

Anyway, the plugin I sent you can't work, as I also changed some abstract classes... please try this version:

Code:

# -*- coding: utf-8 -*-

""" Panohead remote control.

License
=======

 - B{Papywizard} (U{http://www.papywizard.org}) is Copyright:
  - (C) 2007-2010 Frédéric Mantegazza

This software is governed by the B{CeCILL} license under French law and
abiding by the rules of distribution of free software.  You can  use,
modify and/or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
U{http://www.cecill.info}.

As a counterpart to the access to the source code and  rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty  and the software's author,  the holder of the
economic rights,  and the successive licensors  have only  limited
liability.

In this respect, the user's attention is drawn to the risks associated
with loading,  using,  modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean  that it is complicated to manipulate,  and  that  also
therefore means  that it is reserved for developers  and  experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and,  more generally, to use and operate it in the
same conditions as regards security.

The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.

Module purpose
==============

Hardware

Implements
==========

- MerlinOrionHardware
- MerlinOrionAxis
- MerlinOrionAxisController
- MerlinOrionShutter
- MerlinOrionShutterController

@author: Frédéric Mantegazza
@copyright: (C) 2007-2010 Frédéric Mantegazza
@license: CeCILL
@todo: add private methods to MerlinOrionHardware for sending commands to MerlinOrion
"""

__revision__ = "$Id$"

import time
import threading

from PyQt4 import QtCore, QtGui

from papywizard.common import config
from papywizard.common.configManager import ConfigManager
from papywizard.common.loggingServices import Logger
from papywizard.hardware.merlinOrionHardware import MerlinOrionHardware
from papywizard.plugins.pluginsManager  import PluginsManager
from papywizard.plugins.abstractAxisPlugin import AbstractAxisPlugin
from papywizard.plugins.abstractStandardShutterPlugin import AbstractStandardShutterPlugin
from papywizard.plugins.abstractHardwarePlugin import AbstractHardwarePlugin
from papywizard.plugins.axisPluginController import AxisPluginController
from papywizard.plugins.hardwarePluginController import HardwarePluginController
from papywizard.plugins.standardShutterPluginController import StandardShutterPluginController
from papywizard.view.pluginFields import SpinBoxField, DoubleSpinBoxField, CheckBoxField

NAME = "Merlin-Orion"

DEFAULT_ALTERNATE_DRIVE = True
DEFAULT_ALTERNATE_DRIVE_ANGLE = 7. # °
DEFAULT_INERTIA_ANGLE = 1. # °

TAB_HARD = unicode(QtGui.QApplication.translate("merlinOrionPlugins", 'Hard'))
LABEL_ALTERNATE_DRIVE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Alternate drive"))
LABEL_ALTERNATE_DRIVE_ANGLE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Alternate drive angle"))
LABEL_INERTIA_ANGLE = unicode(QtGui.QApplication.translate("merlinOrionPlugins", "Inertia angle"))

AXIS_ACCURACY = 0.1 # °
AXIS_TABLE = {'yawAxis': 1,
              'pitchAxis': 2,
              'shutter': 1
              }
MANUAL_SPEED_TABLE = {'slow': 170,  # "AA0000"  / 5
                      'alternate': 80, # "500000"
                      'normal': 34, # "220000" nominal
                      'fast': 17   # "110000"  * 2
                      }


class MerlinOrionAxis(AbstractHardwarePlugin, AbstractAxisPlugin, QtCore.QThread):
    """
    """
    def __init__(self, *args, **kwargs):
        AbstractHardwarePlugin.__init__(self, *args, **kwargs)  # Only 1?
        AbstractAxisPlugin.__init__(self, *args, **kwargs)
        QtCore.QThread.__init__(self)

    def _init(self):
        Logger().trace("MerlinOrionAxis._init()")
        AbstractHardwarePlugin._init(self)
        AbstractAxisPlugin._init(self)
        self._hardware = MerlinOrionHardware()
        self.__run = False
        self.__driveFlag = False
        self.__setPoint = None

    def _defineConfig(self):
        AbstractAxisPlugin._defineConfig(self)
        AbstractHardwarePlugin._defineConfig(self)
        self._addConfigKey('_alternateDrive', 'ALTERNATE_DRIVE', default=DEFAULT_ALTERNATE_DRIVE)
        self._addConfigKey('_alternateDrive', 'ALTERNATE_DRIVE_ANGLE', default=DEFAULT_ALTERNATE_DRIVE_ANGLE)
        self._addConfigKey('_inertiaAngle', 'INERTIA_ANGLE', default=DEFAULT_INERTIA_ANGLE)

    def activate(self):
        Logger().trace("MerlinOrionHardware.activate()")
        AbstractAxisPlugin.activate(self)

        # Start the thread
        self.start()

    def deactivate(self):
        Logger().trace("MerlinOrionHardware.deactivate()")

        # Stop the thread
        self._stopThread()
        self.wait()
        AbstractAxisPlugin.deactivate(self)

    def init(self):
        Logger().trace("MerlinOrionAxis.init()")
        self._hardware.setAxis(AXIS_TABLE[self.capacity]),
        AbstractHardwarePlugin.init(self)

    def shutdown(self):
        Logger().trace("MerlinOrionAxis.shutdown()")
        self.stop()
        AbstractHardwarePlugin.shutdown(self)
        AbstractAxisPlugin.shutdown(self)

    def run(self):
        """ Main entry of the thread.
        """
        threadName = "%s_%s" % (self.name, self.capacity)
        threading.currentThread().setName(threadName)
        Logger().debug("MerlinOrionAxis.run(): start thread")
        self.__run = True
        while self.__run:
            if self.__driveFlag:

                # Choose alternate drive if needed
                currentPos = self.read()
                if self._config['ALTERNATE_DRIVE'] and \
                   1.1 * self._config['INERTIA_ANGLE'] < abs(self.__setPoint - currentPos) < self._config['ALTERNATE_DRIVE_ANGLE']:
                    self._alternateDrive(self.__setPoint)
                else:
                    self._directDrive(self.__setPoint)
                self.__driveFlag = False
                self.waitEndOfDrive()  # ???

            self.msleep(config.SPY_REFRESH_DELAY)

        Logger().debug("MerlinOrionAxis.run(): thread terminated")

    def _stopThread(self):
        """ Stop the thread.
        """
        self.__run = False

    def read(self):
        pos = self._hardware.read() - self._offset
        return pos

    def drive(self, pos, useOffset=True, wait=True):
        Logger().debug("MerlinOrionAxis.drive(): '%s' drive to %.1f" % (self.capacity, pos))
        currentPos = self.read()

        self._checkLimits(pos)

        # Only move if needed
        if abs(pos - currentPos) > AXIS_ACCURACY or not useOffset:
            if useOffset:
                Logger().debug("MerlinOrionAxis.drive(): offset=%.1f" % self._offset)
                pos += self._offset

            self.__setPoint = pos
            self.__driveFlag = True # Start thread action

            # Wait end of movement
            if wait:
                self.waitEndOfDrive()

    def _directDrive(self, pos):
        """ Default (hardware) drive.

        @param pos: position to reach, in °
        @type pos: float
        """
        Logger().trace("MerlinOrionAxis._directDrive()")
        self._hardware.drive(pos)

    def _alternateDrive(self, pos):
        """ Alternate drive.

        This method implements an external closed-loop regulation.
        It is faster for angles < 6-7°, because in this case, the
        head does not accelerate to full speed, but rather stays at
        very low speed.

        @param pos: position to reach, in °
        @type pos: float
        """
        Logger().trace("MerlinOrionAxis._alternateDrive()")

        # Compute initial direction
        currentPos = self.read()
        if pos > currentPos:
            dir_ = '+'
        else:
            dir_ = '-'
        stopRequest = False

        # Alternate speed move
        Logger().debug("MerlinOrionAxis._alternateDrive(): alternate speed move")
        self._hardware.startJog(dir_, MANUAL_SPEED_TABLE['alternate'])

        # Check when stop
        while abs(pos - self.read()) > self._config['INERTIA_ANGLE']:

            # Test if a stop request has been sent
            if not self.isMoving():
                stopRequest = True
                break
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        self._hardware.stop()

        # Final move
        if not stopRequest:
            Logger().debug("MerlinOrionAxis._alternateDrive(): final move")
            self._hardware.drive(pos)

    def waitEndOfDrive(self):
        while self.isMoving():
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        self.waitStop()

    def startJog(self, dir_):
        self._hardware.startJog(dir_, MANUAL_SPEED_TABLE[self._manualSpeed])

    def stop(self):
        self.__driveFlag = False
        self._hardware.stop()
        self.waitStop()

    def waitStop(self):
        pos = self.read()
        time.sleep(config.SPY_REFRESH_DELAY / 1000.)
        while True:
            if abs(pos - self.read()) <= AXIS_ACCURACY:
                break
            pos = self.read()
            time.sleep(config.SPY_REFRESH_DELAY / 1000.)

    def isMoving(self):
        status = self._hardware.getStatus()
        if status[1] != '0' or self.__driveFlag:
            return True
        else:
            return False


class MerlinOrionAxisController(AxisPluginController, HardwarePluginController):
    def _defineGui(self):
        AxisPluginController._defineGui(self)
        HardwarePluginController._defineGui(self)
        self._addTab('Hard', TAB_HARD)
        self._addWidget('Hard', LABEL_ALTERNATE_DRIVE, CheckBoxField, (), 'ALTERNATE_DRIVE')
        self._addWidget('Hard', LABEL_ALTERNATE_DRIVE_ANGLE, SpinBoxField, (3, 15, "", u" °"), 'ALTERNATE_DRIVE_ANGLE')
        self._addWidget('Hard', LABEL_INERTIA_ANGLE, DoubleSpinBoxField, (0.1, 9.9, 1, .1, "", u" °"), 'INERTIA_ANGLE')


class MerlinOrionShutter(AbstractHardwarePlugin, AbstractStandardShutterPlugin):
    def __init__(self, *args, **kwargs):
        """
        """
        AbstractHardwarePlugin.__init__(self, *args, **kwargs)
        AbstractStandardShutterPlugin.__init__(self, *args, **kwargs)

    def _init(self):
        Logger().trace("MerlinOrionShutter._init()")
        AbstractHardwarePlugin._init(self)
        AbstractStandardShutterPlugin._init(self)
        self._hardware = MerlinOrionHardware()

    def _defineConfig(self):
        AbstractHardwarePlugin._defineConfig(self)
        AbstractStandardShutterPlugin._defineConfig(self)

    def _triggerOnShutter(self):
        """ Set the shutter on.
        """
        self._hardware.setOutput(True)

    def _triggerOffShutter(self):
        """ Set the shutter off.
        """
        self._hardware.setOutput(False)

    def init(self):  # Move to AbstractHardwarePlugin?
        Logger().trace("MerlinOrionShutter.init()")
        self._hardware.setAxis(AXIS_TABLE[self.capacity]),
        AbstractHardwarePlugin.init(self)

    def shutdown(self):
        Logger().trace("MerlinOrionShutter.shutdown()")
        self._triggerOffShutter()
        AbstractHardwarePlugin.shutdown(self)
        AbstractStandardShutterPlugin.shutdown(self)


class MerlinOrionShutterController(StandardShutterPluginController, HardwarePluginController):
    def _defineGui(self):
        StandardShutterPluginController._defineGui(self)
        HardwarePluginController._defineGui(self)


def register():
    """ Register plugins.
    """
    PluginsManager().register(MerlinOrionAxis, MerlinOrionAxisController, capacity='yawAxis', name=NAME)
    PluginsManager().register(MerlinOrionAxis, MerlinOrionAxisController, capacity='pitchAxis', name=NAME)
    PluginsManager().register(MerlinOrionShutter, MerlinOrionShutterController, capacity='shutter', name=NAME)

Frédéric

Canon 20D + 17-40/f4 L USM + 70-200/f4 L USM + 50/f1.4 USM
Merlin/Orion panohead + Papywizard on Nokia N800 and HP TC-1100

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson