Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
moberg
Commits
ee9be737
Commit
ee9be737
authored
Apr 01, 2019
by
Anders Blomdell
Browse files
Return the actual value from write operations
parent
da5d119e
Changes
15
Hide whitespace changes
Inline
Side-by-side
adaptors/java/src/se/lth/control/realtime/moberg/Moberg.java
View file @
ee9be737
...
...
@@ -28,7 +28,7 @@ public class Moberg {
public
static
native
void
analogOutOpen
(
int
index
)
throws
MobergException
;
public
static
native
void
analogOutClose
(
int
index
)
throws
MobergException
;
public
static
native
void
analogOut
(
int
index
,
double
value
)
throws
MobergException
;
public
static
native
double
analogOut
(
int
index
,
double
value
)
throws
MobergException
;
public
static
native
void
digitalInOpen
(
int
index
)
throws
MobergException
;
public
static
native
void
digitalInClose
(
int
index
)
throws
MobergException
;
...
...
@@ -36,7 +36,7 @@ public class Moberg {
public
static
native
void
digitalOutOpen
(
int
index
)
throws
MobergException
;
public
static
native
void
digitalOutClose
(
int
index
)
throws
MobergException
;
public
static
native
void
digitalOut
(
int
index
,
boolean
value
)
throws
MobergException
;
public
static
native
boolean
digitalOut
(
int
index
,
boolean
value
)
throws
MobergException
;
public
static
native
void
encoderInOpen
(
int
index
)
throws
MobergException
;
public
static
native
void
encoderInClose
(
int
index
)
throws
MobergException
;
...
...
adaptors/java/src/se_lth_control_realtime_moberg_Moberg.c
View file @
ee9be737
...
...
@@ -261,16 +261,19 @@ Java_se_lth_control_realtime_moberg_Moberg_analogOutClose(
}
JNIEXPORT
void
JNICALL
JNIEXPORT
double
JNICALL
Java_se_lth_control_realtime_moberg_Moberg_analogOut
(
JNIEnv
*
env
,
jobject
obj
,
jint
index
,
jdouble
value
JNIEnv
*
env
,
jobject
obj
,
jint
index
,
jdouble
desired
)
{
struct
channel
*
channel
=
channel_get
(
&
analog_out
,
index
);
if
(
!
channel
)
{
throwMobergNotOpenException
(
env
,
index
);
return
0
.
0
;
}
else
{
channel
->
analog_out
.
write
(
channel
->
analog_out
.
context
,
value
);
double
actual
;
channel
->
analog_out
.
write
(
channel
->
analog_out
.
context
,
desired
,
&
actual
);
return
actual
;
}
}
...
...
@@ -354,16 +357,19 @@ Java_se_lth_control_realtime_moberg_Moberg_digitalOutClose(
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
jboolean
JNICALL
Java_se_lth_control_realtime_moberg_Moberg_digitalOut
(
JNIEnv
*
env
,
jobject
obj
,
jint
index
,
jboolean
value
JNIEnv
*
env
,
jobject
obj
,
jint
index
,
jboolean
desired
)
{
struct
channel
*
channel
=
channel_get
(
&
digital_out
,
index
);
if
(
!
channel
)
{
throwMobergNotOpenException
(
env
,
index
);
return
0
;
}
else
{
channel
->
digital_out
.
write
(
channel
->
digital_out
.
context
,
value
);
int
actual
;
channel
->
digital_out
.
write
(
channel
->
digital_out
.
context
,
desired
,
&
actual
);
return
actual
;
}
}
...
...
adaptors/julia/AnalogOut.jl
View file @
ee9be737
...
...
@@ -29,8 +29,10 @@ function close(aout::AnalogOut)
end
function
write
(
aout
::
AnalogOut
,
value
::
Cdouble
)
result
=
Ref
{
Cdouble
}(
0.0
)
checkOK
(
ccall
(
aout
.
channel
.
write
,
Status
,
(
Ptr
{
Nothing
},
Cdouble
),
aout
.
channel
.
context
,
value
))
(
Ptr
{
Nothing
},
Cdouble
,
Ptr
{
Cdouble
}),
aout
.
channel
.
context
,
value
,
result
))
return
result
[];
end
adaptors/julia/DigitalOut.jl
View file @
ee9be737
...
...
@@ -29,8 +29,10 @@ function close(dout::DigitalOut)
end
function
write
(
dout
::
DigitalOut
,
value
::
Bool
)
result
=
Ref
{
Cint
}(
0
)
checkOK
(
ccall
(
dout
.
channel
.
write
,
Status
,
(
Ptr
{
Nothing
},
Cint
),
dout
.
channel
.
context
,
value
?
1
:
0
))
(
Ptr
{
Nothing
},
Cint
,
Ptr
{
Cint
}),
dout
.
channel
.
context
,
value
?
1
:
0
,
result
))
return
result
[]
!=
0
end
adaptors/matlab/analogout.c
View file @
ee9be737
...
...
@@ -136,7 +136,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
for
(
i
=
0
;
i
<
ssGetNumPWork
(
S
)
;
i
++
)
{
struct
moberg_analog_out
*
aout
=
(
struct
moberg_analog_out
*
)
pwork
[
i
];
if
(
!
moberg_OK
(
aout
->
write
(
aout
->
context
,
*
up
[
i
])))
{
if
(
!
moberg_OK
(
aout
->
write
(
aout
->
context
,
*
up
[
i
]
,
NULL
)))
{
static
char
error
[
256
];
double
*
channel
=
mxGetPr
(
ssGetSFcnParam
(
S
,
1
));
sprintf
(
error
,
"Failed to write analogout #%d"
,
(
int
)
channel
[
i
]);
...
...
adaptors/matlab/digitalout.c
View file @
ee9be737
...
...
@@ -136,7 +136,7 @@ static void mdlOutputs(SimStruct *S, int_T tid)
for
(
i
=
0
;
i
<
ssGetNumPWork
(
S
)
;
i
++
)
{
struct
moberg_digital_out
*
dout
=
(
struct
moberg_digital_out
*
)
pwork
[
i
];
if
(
!
moberg_OK
(
dout
->
write
(
dout
->
context
,
*
up
[
i
])))
{
if
(
!
moberg_OK
(
dout
->
write
(
dout
->
context
,
*
up
[
i
]
,
NULL
)))
{
static
char
error
[
256
];
double
*
channel
=
mxGetPr
(
ssGetSFcnParam
(
S
,
1
));
sprintf
(
error
,
"Failed to write digitalout #%d"
,
(
int
)
channel
[
i
]);
...
...
adaptors/python/python-moberg.c
View file @
ee9be737
...
...
@@ -276,7 +276,7 @@ MobergAnalogIn_read(MobergAnalogInObject *self, PyObject *Py_UNUSED(ignored))
PyErr_Format
(
PyExc_OSError
,
"moberg._AnalogIn(%d).read() failed with %d"
,
self
->
index
,
status
.
result
);
}
return
Py_BuildValue
(
"
f
"
,
value
);
return
Py_BuildValue
(
"
d
"
,
value
);
}
static
PyMethodDef
MobergAnalogIn_methods
[]
=
{
...
...
@@ -373,19 +373,20 @@ MobergAnalogOut_init(MobergAnalogOutObject *self, PyObject *args, PyObject *kwds
static
PyObject
*
MobergAnalogOut_write
(
MobergAnalogOutObject
*
self
,
PyObject
*
args
)
{
double
value
=
1
.
23
;
if
(
!
PyArg_ParseTuple
(
args
,
"d"
,
&
value
))
{
double
desired_value
,
actual_value
;
if
(
!
PyArg_ParseTuple
(
args
,
"d"
,
&
desired_
value
))
{
goto
err
;
}
struct
moberg_status
status
=
self
->
channel
.
write
(
self
->
channel
.
context
,
value
);
desired_value
,
&
actual_value
);
if
(
!
moberg_OK
(
status
))
{
PyErr_Format
(
PyExc_OSError
,
"moberg._AnalogOut(%d).write() failed with %d"
,
self
->
index
,
status
.
result
);
goto
err
;
}
Py_INCREF
(
Py_None
);
return
Py_
None
;
return
Py_
BuildValue
(
"d"
,
actual_value
)
;
err:
return
NULL
;
}
...
...
@@ -588,19 +589,20 @@ MobergDigitalOut_init(MobergDigitalOutObject *self, PyObject *args, PyObject *kw
static
PyObject
*
MobergDigitalOut_write
(
MobergDigitalOutObject
*
self
,
PyObject
*
args
)
{
double
value
=
1
.
23
;
if
(
!
PyArg_ParseTuple
(
args
,
"d"
,
&
value
))
{
PyObject
*
desired
;
int
actual
;
if
(
!
PyArg_ParseTuple
(
args
,
"O"
,
&
desired
))
{
goto
err
;
}
struct
moberg_status
status
=
self
->
channel
.
write
(
self
->
channel
.
context
,
value
);
PyObject_IsTrue
(
desired
),
&
actual
);
if
(
!
moberg_OK
(
status
))
{
PyErr_Format
(
PyExc_OSError
,
"moberg._DigitalOut(%d).write() failed with %d"
,
self
->
index
,
status
.
result
);
goto
err
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_BuildValue
(
"O"
,
actual
?
Py_True
:
Py_False
);
err:
return
NULL
;
}
...
...
moberg.h
View file @
ee9be737
...
...
@@ -53,7 +53,8 @@ struct moberg_analog_in {
struct
moberg_analog_out
{
struct
moberg_channel_analog_out
*
context
;
struct
moberg_status
(
*
write
)(
struct
moberg_channel_analog_out
*
,
double
value
);
double
desired_value
,
double
*
actual_value
);
};
struct
moberg_digital_in
{
...
...
@@ -65,7 +66,8 @@ struct moberg_digital_in {
struct
moberg_digital_out
{
struct
moberg_channel_digital_out
*
context
;
struct
moberg_status
(
*
write
)(
struct
moberg_channel_digital_out
*
,
int
value
);
int
desired_value
,
int
*
actual_value
);
};
struct
moberg_encoder_in
{
...
...
plugins/comedi/comedi.c
View file @
ee9be737
...
...
@@ -112,16 +112,17 @@ err_errno:
static
struct
moberg_status
analog_out_write
(
struct
moberg_channel_analog_out
*
analog_out
,
double
value
)
double
desired_value
,
double
*
actual_value
)
{
struct
channel_descriptor
descriptor
=
analog_out
->
channel_context
.
descriptor
;
lsampl_t
data
;
if
(
value
<
descriptor
.
min
)
{
if
(
desired_
value
<
descriptor
.
min
)
{
data
=
0
;
}
else
if
(
value
>
descriptor
.
max
)
{
}
else
if
(
desired_
value
>
descriptor
.
max
)
{
data
=
descriptor
.
maxdata
;
}
else
{
data
=
(
value
-
descriptor
.
min
)
/
descriptor
.
delta
;
data
=
(
desired_
value
-
descriptor
.
min
)
/
descriptor
.
delta
;
}
if
(
data
<
0
)
{
data
=
0
;
...
...
@@ -134,6 +135,10 @@ static struct moberg_status analog_out_write(
0
,
0
,
data
))
{
goto
err_errno
;
}
if
(
actual_value
)
{
*
actual_value
=
data
*
descriptor
.
delta
+
descriptor
.
min
;
}
return
MOBERG_OK
;
err_errno:
return
MOBERG_ERRNO
(
comedi_errno
());
...
...
@@ -162,16 +167,20 @@ err_errno:
static
struct
moberg_status
digital_out_write
(
struct
moberg_channel_digital_out
*
digital_out
,
int
value
)
int
desired_value
,
int
*
actual_value
)
{
struct
channel_descriptor
descriptor
=
digital_out
->
channel_context
.
descriptor
;
lsampl_t
data
=
value
==
0
?
0
:
1
;
lsampl_t
data
=
desired_
value
==
0
?
0
:
1
;
if
(
0
>
comedi_data_write
(
digital_out
->
channel_context
.
device
->
comedi
.
handle
,
descriptor
.
subdevice
,
descriptor
.
subchannel
,
0
,
0
,
data
))
{
goto
err_errno
;
}
if
(
actual_value
)
{
*
actual_value
=
data
;
}
return
MOBERG_OK
;
err_errno:
return
MOBERG_ERRNO
(
comedi_errno
());
...
...
plugins/libtest/libtest.c
View file @
ee9be737
...
...
@@ -96,11 +96,15 @@ err_einval:
static
struct
moberg_status
analog_out_write
(
struct
moberg_channel_analog_out
*
analog_out
,
double
value
)
double
desired_value
,
double
*
actual_value
)
{
struct
moberg_channel_context
*
channel
=
&
analog_out
->
channel_context
;
struct
moberg_device_context
*
device
=
channel
->
device
;
device
->
analog
=
value
*
(
channel
->
index
+
1
);
device
->
analog
=
desired_value
*
(
channel
->
index
+
1
);
if
(
actual_value
)
{
*
actual_value
=
desired_value
;
}
return
MOBERG_OK
;
}
...
...
@@ -120,16 +124,20 @@ err_einval:
static
struct
moberg_status
digital_out_write
(
struct
moberg_channel_digital_out
*
digital_out
,
int
value
)
int
desired_value
,
int
*
actual_value
)
{
struct
moberg_channel_context
*
channel
=
&
digital_out
->
channel_context
;
struct
moberg_device_context
*
device
=
channel
->
device
;
int
mask
=
(
1
<<
channel
->
index
);
if
(
value
)
{
if
(
desired_
value
)
{
device
->
digital
|=
mask
;
}
else
{
device
->
digital
&=
~
mask
;
}
if
(
actual_value
)
{
*
actual_value
=
desired_value
;
}
return
MOBERG_OK
;
}
...
...
plugins/serial2002/serial2002.c
View file @
ee9be737
...
...
@@ -128,12 +128,13 @@ err_einval:
static
struct
moberg_status
analog_out_write
(
struct
moberg_channel_analog_out
*
analog_out
,
double
value
)
double
desired_value
,
double
*
actual_value
)
{
struct
moberg_channel_context
*
channel
=
&
analog_out
->
channel_context
;
struct
moberg_device_context
*
device
=
channel
->
device
;
struct
analog_map
map
=
device
->
analog_out
.
map
[
channel
->
index
];
long
as_long
=
(
value
-
map
.
min
)
/
map
.
delta
;
long
as_long
=
(
desired_
value
-
map
.
min
)
/
map
.
delta
;
if
(
as_long
<
0
)
{
as_long
=
0
;
}
else
if
(
as_long
>
map
.
maxdata
)
{
...
...
@@ -141,7 +142,11 @@ static struct moberg_status analog_out_write(
}
struct
serial2002_data
data
=
{
is_channel
,
map
.
index
,
as_long
};
return
serial2002_write
(
device
->
port
.
fd
,
data
);
struct
moberg_status
result
=
serial2002_write
(
device
->
port
.
fd
,
data
);
if
(
OK
(
result
)
&&
actual_value
)
{
*
actual_value
=
data
.
value
*
map
.
delta
+
map
.
min
;
}
return
result
;
}
static
struct
moberg_status
digital_in_read
(
...
...
@@ -173,13 +178,18 @@ err_einval:
static
struct
moberg_status
digital_out_write
(
struct
moberg_channel_digital_out
*
digital_out
,
int
value
)
int
desired_value
,
int
*
actual_value
)
{
struct
moberg_channel_context
*
channel
=
&
digital_out
->
channel_context
;
struct
moberg_device_context
*
device
=
channel
->
device
;
struct
digital_map
map
=
device
->
digital_out
.
map
[
channel
->
index
];
struct
serial2002_data
data
=
{
is_digital
,
map
.
index
,
value
!=
0
};
return
serial2002_write
(
device
->
port
.
fd
,
data
);
struct
serial2002_data
data
=
{
is_digital
,
map
.
index
,
desired_value
!=
0
};
struct
moberg_status
result
=
serial2002_write
(
device
->
port
.
fd
,
data
);
if
(
OK
(
result
)
&&
actual_value
)
{
*
actual_value
=
data
.
value
;
}
return
result
;
}
static
struct
moberg_status
encoder_in_read
(
...
...
test/Makefile
View file @
ee9be737
...
...
@@ -14,12 +14,13 @@ PYTHON3PATH=$(shell realpath ../adaptors/python/install/usr/lib*/python3*/site-p
all
:
.PHONY
:
test
test
:
$(PYTEST:%=run_py_%) $(JULIATEST:%=run_jl_%)
$(CTEST:%=run_c_%)
test
:
$(CTEST:%=run_c_%)
$(PYTEST:%=run_py_%) $(JULIATEST:%=run_jl_%)
echo
Tests run
.PHONY
:
run_c_%
run_c_%
:
build/%
$(ENV_TEST)
valgrind
--leak-check
=
full ./build/
$*
env
-i
LD_LIBRARY_PATH
=
../build valgrind
--leak-check
=
full ./build/
$*
.PHONY
:
run_py_%
run_py_%
:
%.py
...
...
test/test_io.c
View file @
ee9be737
...
...
@@ -10,7 +10,7 @@ int main(int argc, char *argv[])
}
struct
moberg_analog_in
ai0
;
struct
moberg_analog_out
ao0
;
double
ai0_value
;
double
ai0_value
,
ao0_actual
;
if
(
!
moberg_OK
(
moberg_analog_in_open
(
moberg
,
0
,
&
ai0
)))
{
fprintf
(
stderr
,
"OPEN failed
\n
"
);
goto
free
;
...
...
@@ -24,11 +24,11 @@ int main(int argc, char *argv[])
fprintf
(
stderr
,
"OPEN failed
\n
"
);
goto
free
;
}
if
(
!
moberg_OK
(
ao0
.
write
(
ao0
.
context
,
ai0_value
*
2
)))
{
if
(
!
moberg_OK
(
ao0
.
write
(
ao0
.
context
,
ai0_value
*
2
,
&
ao0_actual
)))
{
fprintf
(
stderr
,
"READ failed
\n
"
);
goto
close_ao0
;
}
fprintf
(
stderr
,
"WROTE ao0: %f
\n
"
,
ai0_value
*
2
);
fprintf
(
stderr
,
"WROTE ao0:
%f
%f
\n
"
,
ai0_value
*
2
,
ao0_actual
);
close_ao0:
moberg_analog_out_close
(
moberg
,
0
,
ao0
);
close_ai0:
...
...
test/test_jl.jl
View file @
ee9be737
...
...
@@ -7,33 +7,32 @@ import MobergIO: read, write
function
test
()
m
=
MobergIO
.
Moberg
()
println
(
stderr
,
m
)
println
(
m
)
for
v
in
-
10.0
:
2.0
:
10
for
i
in
0
:
1
try
aout
=
MobergIO
.
AnalogOut
(
m
,
Unsigned
(
i
))
value
=
v
+
i
;
write
(
aout
,
value
)
print
(
"
$
value
"
)
actual
=
write
(
aout
,
value
)
print
(
"
(
$
value
,
$
actual)
"
)
catch
ex
println
(
stderr
,
"analog_out
$
i does not exist
$(ex)
"
)
end
end
println
(
stderr
)
flush
(
stderr
)
println
()
sleep
(
0.01
)
for
j
in
0
:
3
try
ain
=
MobergIO
.
AnalogIn
(
m
,
Unsigned
(
j
))
println
(
stderr
,
read
(
ain
))
catch
ex
println
(
stderr
,
"analog_in
$
j does not exist
$(ex)
"
)
println
(
"analog_in
$
j does not exist
$(ex)
"
)
end
flush
(
std
err
)
flush
(
std
out
)
end
println
(
stderr
)
flush
(
std
err
)
println
()
flush
(
std
out
)
end
for
v
in
false
:
true
for
i
in
0
:
6
...
...
@@ -43,34 +42,34 @@ function test()
write
(
dout
,
value
)
print
(
"
$
value "
)
catch
ex
println
(
stderr
,
"digital_out
$
i does not exist
$(ex)
"
)
println
(
"digital_out
$
i does not exist
$(ex)
"
)
end
flush
(
std
err
)
flush
(
std
out
)
end
println
(
stderr
)
flush
(
std
err
)
println
()
flush
(
std
out
)
for
i
in
0
:
6
try
din
=
MobergIO
.
DigitalIn
(
m
,
Unsigned
(
i
))
print
(
"
$
(read(din)) "
)
catch
ex
println
(
stderr
,
"digital_in
$
i does not exist
$(ex)
"
)
println
(
"digital_in
$
i does not exist
$(ex)
"
)
end
flush
(
std
err
)
flush
(
std
out
)
end
println
(
stderr
)
println
(
stderr
)
println
()
println
()
sleep
(
0.01
)
end
end
test
()
println
(
stderr
,
"DONE"
)
flush
(
std
err
)
println
(
"DONE"
)
flush
(
std
out
)
GC
.
gc
()
println
(
stderr
,
"...."
)
flush
(
std
err
)
println
(
"...."
)
flush
(
std
out
)
GC
.
gc
()
# See https://github.com/JuliaCI/BenchmarkTools.jl/blob/af35d0513fe1e336ad0d8b9a35f924e8461aefa2/src/execution.jl#L1
println
(
stderr
,
"Really DONE"
)
flush
(
std
err
)
println
(
"Really DONE"
)
flush
(
std
out
)
test/test_start_stop.c
View file @
ee9be737
...
...
@@ -3,11 +3,13 @@
int
main
(
int
argc
,
char
*
argv
[])
{
fprintf
(
stderr
,
"NEW
\n
"
);
struct
moberg
*
moberg
=
moberg_new
(
NULL
);
printf
(
"START:
\n
"
);
f
printf
(
stderr
,
"START:
\n
"
);
moberg_start
(
moberg
,
stdout
);
printf
(
"STOP:
\n
"
);
f
printf
(
stderr
,
"STOP:
\n
"
);
moberg_stop
(
moberg
,
stdout
);
printf
(
"DON
E
\n
"
);
f
printf
(
stderr
,
"FRE
E
\n
"
);
moberg_free
(
moberg
);
fprintf
(
stderr
,
"DONE
\n
"
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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