Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Alisher Gaibulaev
bliss
Commits
90150e08
Commit
90150e08
authored
Jun 28, 2017
by
Alejandro Homs Puron
Browse files
Merge branch 'ID31_robot' into 'ID31_reflectometry'
Id31 robot See merge request
!325
parents
b0c48e52
e0c7e31d
Changes
6
Hide whitespace changes
Inline
Side-by-side
bliss/comm/gpib/_gpib.py
View file @
90150e08
...
...
@@ -15,7 +15,7 @@ from gevent import lock
from
.libnienet
import
EnetSocket
from
..tcp
import
Socket
from
..exceptions
import
CommunicationError
,
CommunicationTimeout
from
...common.greenlet_utils
import
KillMask
from
...common.greenlet_utils
import
KillMask
,
protect_from_kill
try
:
from
collections
import
OrderedDict
...
...
@@ -285,12 +285,14 @@ class Gpib:
def
_write
(
self
,
msg
)
:
return
self
.
_raw_handler
.
ibwrt
(
msg
)
@
protect_from_kill
def
write_read
(
self
,
msg
,
write_synchro
=
None
,
size
=
1
,
timeout
=
None
)
:
with
self
.
_lock
:
self
.
_write
(
msg
)
if
write_synchro
:
write_synchro
.
notify
()
return
self
.
_read
(
size
)
@
protect_from_kill
def
write_readline
(
self
,
msg
,
write_synchro
=
None
,
eol
=
None
,
timeout
=
None
)
:
with
self
.
_lock
:
...
...
@@ -298,6 +300,7 @@ class Gpib:
if
write_synchro
:
write_synchro
.
notify
()
return
self
.
_readline
(
eol
)
@
protect_from_kill
def
write_readlines
(
self
,
msg
,
nb_lines
,
write_synchro
=
None
,
eol
=
None
,
timeout
=
None
):
with
self
.
_lock
:
...
...
bliss/common/greenlet_utils.py
View file @
90150e08
...
...
@@ -22,6 +22,7 @@ class KillMask:
self
.
__greenlet
,
self
.
__exception
,
self
.
__waiter
)
gevent
.
sleep
(
0
)
elif
self
.
__exception
is
not
None
:
get_hub
().
loop
.
run_callback
(
self
.
__greenlet
.
throw
,
self
.
__exception
)
...
...
bliss/controllers/motors/ID31Robot.py
0 → 100644
View file @
90150e08
# -*- 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
time
import
serial
from
bliss.controllers.motor
import
Controller
from
bliss.common
import
log
as
elog
from
bliss.common.axis
import
AxisState
from
bliss.common.utils
import
object_attribute_get
,
object_attribute_set
from
StaubPy
import
id31Controller
"""
Bliss controller for ID31Robot.
"""
class
ID31Robot
(
Controller
):
Cache
=
{}
def
initialize
(
self
):
"""
"""
# opens communication
print
(
"Initialisation of ID31 robot."
)
host
=
self
.
config
.
get
(
'host'
)
try
:
self
.
id31
=
ID31Robot
.
Cache
[
host
]
except
KeyError
:
ID31Robot
.
Cache
[
host
]
=
id31Controller
.
ID31Controller
(
controllerAssociated
=
self
.
config
.
get
(
'host'
))
self
.
id31
=
ID31Robot
.
Cache
[
host
]
print
(
"Creating robot 'firmware' and shipping to controller. (fast)"
)
self
.
id31
.
makeOnly
()
print
(
"Starting new robot controller 'firmware' (takes time (5-25sec))"
)
self
.
id31
.
loadOnly
()
print
(
"Initialising values in controller. (fast)"
)
self
.
id31
.
initValues
()
self
.
movingStatus
=
"initialised"
print
(
"Post Init Actions in controller. (fast)"
)
self
.
id31
.
postInit
()
self
.
id31
.
scanSpeed
.
velocity
=
self
.
config
.
get
(
'speed'
)
self
.
id31
.
printDebug
=
False
def
finalize
(
self
):
"""
"""
# Closes communication
def
initialize_axis
(
self
,
axis
):
"""
Reads specific config
Adds specific methods
"""
axis
.
role
=
axis
.
config
.
get
(
'role'
)
def
read_position
(
self
,
axis
):
"""
Returns position's setpoint or measured position.
Args:
- <axis> : bliss axis.
- [<measured>] : boolean : if True, function returns
measured position in ???
Returns:
- <position> : float : axis setpoint in ???.
"""
return
getattr
(
self
.
id31
,
axis
.
role
)
def
read_encoder
(
self
,
encoder
):
raise
NotImplementedError
# def read_velocity(self, axis):
# """
# Args:
# - <axis> : Bliss axis object.
# Returns:
# - <velocity> : float
# """
# return self.id31.scanSpeed.velocity
# def set_velocity(self, axis, new_velocity):
# #But bliss do not know that other axis velocity changed also.
@
object_attribute_get
(
type_info
=
"float"
)
def
get_speed
(
self
,
axis
):
return
self
.
id31
.
scanSpeed
.
velocity
@
object_attribute_set
(
type_info
=
"float"
)
def
set_speed
(
self
,
axis
,
new_speed
):
self
.
id31
.
scanSpeed
.
velocity
=
new_speed
def
state
(
self
,
axis
):
if
self
.
id31
.
hasMovesProgrammed
:
return
AxisState
(
"MOVING"
)
else
:
return
AxisState
(
"READY"
)
def
prepare_move
(
self
,
motion
):
setattr
(
self
.
id31
,
motion
.
axis
.
role
,
motion
.
target_pos
)
def
start_one
(
self
,
motion
):
"""
"""
print
(
"START one"
,
motion
)
self
.
id31
.
moveToPosition
()
def
start_all
(
self
,
*
motion_list
):
print
(
"START ALL"
,
motion_list
)
self
.
id31
.
moveToPosition
()
def
stop
(
self
,
axis
):
i
=
0
while
self
.
id31
.
hasMovesProgrammed
and
i
<
5
:
self
.
id31
.
resetMotion
()
i
+=
1
if
self
.
id31
.
hasMovesProgrammed
:
logging
.
error
(
'robot still has programmed moves after 5 attempts to stop'
)
bliss/spec/config/config.py
View file @
90150e08
...
...
@@ -9,9 +9,11 @@
Scan a Spec config file to detect instances of a Eurotherm 2400 temp controller.
"""
import
os
import
struct
import
logging
import
datetime
import
collections
__all__
=
[
'SpecConfig'
,
'Device'
,
'Motor'
,
'Counter'
]
...
...
@@ -34,6 +36,8 @@ HEADER_TEMPLATE = """\
# ID Bliss generated config at {timestamp}. All changes will be overwritten!
"""
MotorSettings
=
collections
.
namedtuple
(
'Settings'
,
'accumulator offset, low_limit, high_limit'
)
class
Device
:
"""A device controller, can be PSE_MAC_C, PSE_MAC_MOT, HW_GPIBENET_L SDEV_0 etc."""
...
...
@@ -282,8 +286,8 @@ class Motor:
MOTPAR:step_size_neg = 2.3
"""
def
__init__
(
self
,
line
=
None
,
ctrl
=
None
,
steps
=
2000
,
sign
=
1
,
\
slew
=
2000
,
base
=
200
,
backl
=
50
,
accel
=
125
,
nada
=
'0'
,
\
flags
=
'0x003'
,
mne
=
None
,
name
=
None
):
slew
=
2000
,
base
=
200
,
backl
=
50
,
accel
=
125
,
nada
=
'0'
,
\
flags
=
'0x003'
,
mne
=
None
,
name
=
None
):
self
.
__objecttype
=
'Motor'
MotCorr
=
{
'MAXE_E'
:
'MAXE'
,
'MAXE_D'
:
'MAXE'
}
...
...
@@ -338,6 +342,7 @@ class Motor:
self
.
umc
=
unitchan
.
split
(
'/'
)
if
self
.
ctrl
in
MotCorr
:
self
.
type
=
MotCorr
[
self
.
ctrl
]
self
.
settings
=
MotorSettings
(
0
,
0.
,
0.
,
0.
)
def
setMotNum
(
self
,
num
):
'''
...
...
@@ -392,6 +397,8 @@ class Motor:
else
:
return
None
def
setSettings
(
self
,
accumulator
=
0
,
offset
=
0.
,
low_limit
=
0.
,
high_limit
=
0.
):
self
.
settings
=
MotorSettings
(
int
(
accumulator
),
offset
,
low_limit
,
high_limit
)
class
Counter
:
...
...
@@ -751,8 +758,20 @@ class SpecConfig:
except
:
print
"Unexpected error:"
,
sys
.
exc_info
()[
0
]
raise
f
.
write
(
s
elf
.
__str__
(
))
f
.
write
(
s
tr
(
self
))
f
.
close
()
os
.
chmod
(
file_name
,
0666
)
def
writeSettings
(
self
,
file_name
):
fmt
=
'ifdd'
fmt_size
=
struct
.
calcsize
(
fmt
)
settings
=
bytearray
((
320
*
fmt_size
)
*
'
\0
'
)
for
i
,
motor
in
enumerate
(
self
.
motors
):
motor
.
setMotNum
(
i
)
struct
.
pack_into
(
fmt
,
settings
,
i
*
fmt_size
,
*
motor
.
settings
)
with
open
(
file_name
,
'wb'
)
as
settings_file
:
settings_file
.
write
(
settings
)
os
.
chmod
(
file_name
,
0666
)
def
printalltypes
(
self
):
for
x
in
self
.
devicenodes
:
...
...
bliss/spec/config/generator.py
View file @
90150e08
...
...
@@ -26,8 +26,10 @@ Usage:
import
os
import
socket
import
struct
import
logging
import
datetime
import
platform
import
collections
try
:
...
...
@@ -38,7 +40,7 @@ except AttributeError:
import
tango
from
bliss.config.static
import
get_config
from
bliss.config.settings
import
HashSetting
from
..utils
import
get_config_path
from
.config
import
SpecConfig
,
Device
,
Motor
,
Counter
...
...
@@ -217,6 +219,7 @@ class WagoSetup:
setup
.
append
(
att
)
return
'
\n
'
.
join
(
setup
)
+
'
\n
'
#
# Tango constants
#
...
...
@@ -270,6 +273,20 @@ def TLimaServer(name, host, camera_type, domain):
return
TServer
(
'LimaCCDs'
,
name
,
host
,
devices
)
def
get_os
():
system
=
platform
.
system
()
if
system
==
'Linux'
:
dist
,
ver
,
did
=
platform
.
linux_distribution
()
if
dist
==
'redhat'
:
result
=
'redhat4'
else
:
ver
=
ver
.
split
(
'.'
,
1
)
result
=
dist
+
ver
[
0
]
else
:
result
=
system
return
result
.
lower
()
class
Generator
(
object
):
def
__init__
(
self
,
spec_name
,
config
=
None
,
**
kwargs
):
...
...
@@ -444,18 +461,35 @@ class Generator(object):
# Emotion
####################
def
__settings_to_spec
(
self
,
mot_config
,
settings
):
sign
=
int
(
mot_config
.
get
(
'sign'
,
1
))
dial
=
float
(
settings
.
get
(
'dial_position'
,
0
))
accum
=
int
(
dial
*
float
(
mot_config
.
get
(
'steps_per_unit'
,
1
)))
offset
=
float
(
settings
.
get
(
'offset'
,
0.0
))
try
:
low_limit
=
(
float
(
settings
[
'low_limit'
])
-
offset
)
/
sign
except
KeyError
:
low_limit
=
float
(
mot_config
.
get
(
'low_limit'
,
0.0
))
try
:
high_limit
=
(
float
(
settings
[
'high_limit'
])
-
offset
)
/
sign
except
KeyError
:
high_limit
=
float
(
mot_config
.
get
(
'high_limit'
,
0.0
))
return
accum
,
offset
,
low_limit
,
high_limit
def
__add_emotion_axis_to_spec_controller
(
self
,
name
,
config_name
,
ctrl
):
mot_config
=
self
.
config
.
get_config
(
config_name
)
chan
=
ctrl
.
num
ctrl_addr
=
'MAC_MOT:{0}/{1}'
.
format
(
ctrl
.
getCtrlIndex
(),
chan
)
sign
=
mot_config
.
get
(
'sign'
)
or
1
sign
=
int
(
mot_config
.
get
(
'sign'
,
1
))
spec_motor
=
Motor
(
ctrl
=
ctrl_addr
,
steps
=
int
(
1E6
),
mne
=
name
,
name
=
name
,
sign
=
sign
,
backl
=
0
)
spec_motor
.
addPar
(
'MOTPAR:read_mode = 7'
)
if
config_name
!=
name
:
spec_motor
.
addPar
(
'MOTPAR:axis_name = %s'
%
config_name
)
settings
=
HashSetting
(
'axis.'
+
config_name
)
spec_motor
.
setSettings
(
*
self
.
__settings_to_spec
(
mot_config
,
settings
))
self
.
spec_config
.
addMotor
(
spec_motor
)
ctrl
.
addChannel
(
chan
)
self
.
__spec_macros
.
add
(
'tango_mot.mac'
)
...
...
@@ -494,6 +528,7 @@ class Generator(object):
self
.
spec_config
.
addDevice
(
ctrl
)
self
.
__spec_setup_icepaps
[
icepap
]
=
ctrl
addr
=
cfg
.
pop
(
'address'
)
cfg
.
pop
(
'user_tag'
,
None
)
# remove user tag so that MOTPAR is not generated
module
,
chan
=
addr
.
split
(
'/'
)
addr
=
'MAC_MOT:{0}/{1}'
.
format
(
ctrl
.
getCtrlIndex
(),
addr
)
spec_motor
=
Motor
(
ctrl
=
addr
,
mne
=
name
,
name
=
name
,
...
...
@@ -503,12 +538,15 @@ class Generator(object):
base
=
cfg
.
pop
(
'base'
,
0
),
backl
=
cfg
.
pop
(
'backl'
,
0
),
accel
=
cfg
.
pop
(
'accel'
))
settings
=
HashSetting
(
'axis.'
+
config_name
)
spec_motor
.
setSettings
(
*
self
.
__settings_to_spec
(
config
,
settings
))
for
k
,
v
in
cfg
.
items
():
spec_motor
.
addPar
(
'MOTPAR:{0} = {1}'
.
format
(
k
,
v
))
self
.
spec_config
.
addMotor
(
spec_motor
)
ctrl
.
addChannel
(
chan
)
self
.
__spec_macros
.
add
(
'ice.mac'
)
self
.
__spec_macros
.
add
(
'blissspecmotor.mac'
)
self
.
__spec_setup
.
append
(
'motorsettingssetup %s'
%
name
)
####################
# Wago
...
...
@@ -1029,7 +1067,9 @@ class Generator(object):
unit
=
len
(
gpibs
)
host
=
url
.
strip
(
head
)
conf
=
'@gpib_%s'
%
unit
gpib_ctrl
=
Device
(
ltype
=
'HW_GPIBENET_L'
,
addr
=
host
,
num
=
''
,
conf
=
conf
)
# do not use shared (ie HW_GPIBENET_L) because spec has problems
# with ENET 1000
gpib_ctrl
=
Device
(
ltype
=
'HW_GPIBENET'
,
addr
=
host
,
num
=
''
,
conf
=
conf
)
self
.
spec_config
.
addDevice
(
gpib_ctrl
)
gpibs
[
url
]
=
unit
return
unit
...
...
@@ -1112,6 +1152,7 @@ class Generator(object):
os
.
makedirs
(
output_dir
)
self
.
__generate_spec_config
(
output_dir
)
self
.
__generate_spec_setup
(
output_dir
)
self
.
__generate_spec_settings
(
output_dir
)
def
__generate_spec_config
(
self
,
spec_dir
):
config_file
=
os
.
path
.
join
(
spec_dir
,
'config'
)
...
...
@@ -1139,6 +1180,15 @@ class Generator(object):
self
.
_log
.
debug
(
'writting spec setup file %s'
,
setup_file
)
with
open
(
setup_file
,
'w'
)
as
sf
:
sf
.
write
(
setup_content
)
os
.
chmod
(
setup_file
,
0666
)
def
__generate_spec_settings
(
self
,
spec_dir
):
output_dir
=
os
.
path
.
join
(
spec_dir
,
get_os
())
if
not
os
.
path
.
isdir
(
output_dir
):
os
.
makedirs
(
output_dir
)
settings_file
=
os
.
path
.
join
(
output_dir
,
'settings'
)
self
.
_log
.
debug
(
'writting settings file %s'
,
settings_file
)
self
.
spec_config
.
writeSettings
(
settings_file
)
def
main
():
...
...
spec/blissspecmotor.mac
0 → 100644
View file @
90150e08
need bliss
#################################
# Spec motor settings
#################################
# <motor-mne> ...
def motorsettingssetup '{
local i mne args[] nargs mnum motor_class
if (!BLISS["device"])
blisssetup
nargs = split("$*", args)
if (nargs == 0) {
args[0] = getval("Enter the motor mnemonic", "")
nargs = 1
}
for (i = 0; i < nargs; i++) {
mne = args[i]
mnum = motor_num(mne)
if ((mnum < 0) || (motor_mne(mnum) != mne)) {
printf("Invalid motor: %s\n", mne)
exit
}
}
motor_class = "axis"
bliss_register_settings_class(motor_class, "motor_dump_object_settings", \
"motor_load_object_settings")
for (i = 0; i < nargs; i++) {
mne = args[i]
bliss_add_settings_object(motor_class, mne)
}
setup_tail("motorsettings", "$*")
}'
def motorsettingsunsetup '{
local i mne args[] nargs motor_class
motor_class = "axis"
nargs = split("$*", args)
for (i = 0; i < nargs; i++) {
mne = args[i]
if (bliss_del_settings_object(mne, motor_class))
bliss_unregister_settings_class(motor_class)
}
}'
def motor_dump_object_settings(motor_class, mne) '{
local mnum obj_settings[]
mnum = motor_num(mne)
obj_settings["dial_position"] = dial(mnum, A[mnum])
obj_settings["offset"] = user(mnum, 0)
obj_settings["low_limit"] = user(mnum, get_lim(mnum, -1))
obj_settings["high_limit"] = user(mnum, get_lim(mnum, 1))
return obj_settings
}'
def motor_load_object_settings(motor_class, mne, obj_settings) '{
local mnum
mnum = motor_num(mne)
if (bliss_is_default_settings(obj_settings)) {
printf("Warning: ignoring default settings load for %s!\n", mne)
} else {
local m_dial s_m_dial m_offset s_m_offset
local m_low_limit s_m_low_limit m_high_limit s_m_high_limit
m_dial = dial(mnum, A[mnum])
m_offset = user(mnum, 0)
m_low_limit = user(mnum, get_lim(mnum, -1))
m_high_limit = user(mnum, get_lim(mnum, 1))
s_m_dial = obj_settings["dial_position"]
s_m_offset = obj_settings["offset"]
s_m_low_limit = obj_settings["low_limit"]
s_m_high_limit = obj_settings["high_limit"]
if (s_m_dial != m_dial)
printf("Warning: %s dial_position mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_dial, m_dial)
if (s_m_offset != offset)
printf("Warning: %s offset mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_offset, m_offset)
if (s_m_low_limit != m_low_limit)
printf("Warning: %s low_lim mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_low_limit, m_low_limit)
if (s_m_high_limit != m_high_limit)
printf("Warning: %s high_lim mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_high_limit, m_high_limit)
}
}'
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment