Commit 4621dd96 authored by Emmanuel Papillon's avatar Emmanuel Papillon

* add tab2 controller

parent 16739be9
# -*- coding: utf-8 -*-
"""Top-level package for ID11 project."""
__author__ = """BCU Team"""
__email__ = "papillon@esrf.fr"
__version__ = "0.1.0"
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.
import numpy as np
from bliss.controllers.motor import CalcController
"""
2 legs system
=============
(x)<---------------------------------------
- -
| [dcenter] |
| (C)<---------->|
|<----------------------->|
| [dlegs] |
+ +
back front
Configurations:
* [front] and [back] are two linear translation moving in same direction along y-axis
* [dlegs] is the distance between the two legs (always >0)
* [dcenter] define the center of rotation:
- it can be on left of front leg [dcenter > 0]
- it can be on right of front leg [dcenter < 0]
* [dlegs], [dcenter] are of same units as [front] and [back] motors
which are supposed to have the same units
* [trans] is the calulated y-axis translation of point (C)
* [rot] is the calculated z-axis rotation
default unit of [rot] is mrad. It can be changed to deg or rad
by setting unit config parameter
Example:
controller:
class: tab2
module: tables
dlegs: 200
dcenter: 100
axes:
- name: $tf
tags: real front
- name: $tb
tags: real back
- name: tz
tags: trans
- name: tr
tags: rot
unit: deg [optionnal, default=mrad]
"""
class Tab2(CalcController):
def initialize(self):
CalcController.initialize(self)
self._d = self.config.get("dlegs", float)
self._dc = self.config.get("dcenter", float)
self.__rot_unit = "mrad"
def initialize_axis(self, axis):
if axis.config.get("tags") == "rot":
rot_unit = axis.config.get("unit", str, None)
if rot_unit is None:
axis.config.set("unit", self.__rot_unit)
else:
self.__rot_unit = rot_unit
if axis.config.get("tags") == "trans":
tr_unit = axis.config.get("unit", str, None)
if tr_unit is None:
front_unit = self._tagged["front"][0].unit
back_unit = self._tagged["back"][0].unit
if front_unit == back_unit and front_unit is not None:
axis.config.set("unit", front_unit)
@property
def center(self):
return self._dc
@center.setter
def center(self, new_dc):
self._dc = new_dc
self._real_position_update()
def calc_from_real(self, positions_dict):
tf = positions_dict["front"]
tb = positions_dict["back"]
d = self._d
dc = self._dc
rot = np.arctan((tb - tf) / d)
trans = tf + dc * ((tb - tf) / d)
if self.__rot_unit == "deg":
rot = np.degrees(rot)
elif self.__rot_unit == "mrad":
rot *= 1000.0
return {"rot": rot, "trans": trans}
def calc_to_real(self, positions_dict):
th = positions_dict["trans"]
tr = positions_dict["rot"]
d = self._d
dc = self._dc
if self.__rot_unit == "deg":
tr = np.radians(tr)
elif self.__rot_unit == "mrad":
tr /= 1000.0
front = th - dc * np.tan(tr)
back = th + (d - dc) * np.tan(tr)
return {"front": front, "back": back}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment