Revision 2df0ddb0

View differences:

CMakeLists.txt
1
cmake_minimum_required(VERSION 2.8.3)
2
project(humotion)
3

  
4
set(ENV{ROS_LANG_DISABLE} "genjava")
5

  
6
set(ROS_BUILD_TYPE Debug)
7

  
8
################################################################
9
# check for ROS support:
10
find_package(catkin REQUIRED COMPONENTS
11
    roscpp
12
    std_msgs
13
    sensor_msgs
14
    message_generation
15
    genmsg
16
    dynamic_reconfigure
17
)
18

  
19
IF (NOT catkin_FOUND)
20
  MESSAGE(FATAL_ERROR "Error: could not find ROS middleware!")
21
ENDIF (NOT catkin_FOUND)
22

  
23
INCLUDE(FindPkgConfig)
24

  
25
##libreflexxes
26
#IF (libreflexxes_DIR)
27
#  MESSAGE("using libreflexxes_DIR as override ('${libreflexxes_DIR}')")
28
#  SET(REFLEXXES_PREFIX ${libreflexxes_DIR})
29
#  SET(REFLEXXES_LIBRARY "ReflexxesTypeII")
30
#ELSE ()
31
  PKG_CHECK_MODULES(REFLEXXES REQUIRED libReflexxesTypeII>=1.2.3)
32
  IF (NOT REFLEXXES_FOUND)
33
    message(FATAL_ERROR "Error: could not find lib libReflexxesTypeII")
34
  ENDIF ()
35
#ENDIF ()
36

  
37

  
38
SET(REFLEXXES_LIBRARY_DIRS "${REFLEXXES_PREFIX}/lib")
39
SET(REFLEXXES_INCLUDE_DIRS "${REFLEXXES_PREFIX}/include")
40
#resolve to absolute library filename
41
#or is there an easier way to get the absolute lib filename from pkg config files?!
42
find_library(REFLEXXES_LIBRARY NAMES ${REFLEXXES_LIBRARIES} HINTS ${REFLEXXES_LIBRARY_DIRS})
43

  
44
MESSAGE("-- using libReflexxesTypeII version ${REFLEXXES_VERSION} from ${REFLEXXES_INCLUDE_DIRS} and ${REFLEXXES_LIBRARY_DIRS}")
45
MESSAGE("-- will link against ${REFLEXXES_LIBRARY}")
46

  
47
set(CMAKE_CXX_FLAGS "-g -Wall")
48
add_definitions ("-Wall")
49

  
50
#######################################
51
## Declare ROS messages and services ##
52
#######################################
53

  
54
add_message_files(
55
        FILES
56
        gaze.msg
57
        position_lcr.msg
58
        mouth.msg
59
)
60

  
61
## Generate added messages and services with any dependencies listed here
62
generate_messages(
63
        DEPENDENCIES
64
        std_msgs
65
        humotion
66
)
67

  
68
# add dynamic reconfigure api
69
generate_dynamic_reconfigure_options(
70
  cfg/humotion.cfg
71
)
72

  
73
#
74
###################################
75
## catkin specific configuration ##
76
###################################
77
## The catkin_package macro generates cmake config files for your package
78
## Declare things to be passed to dependent projects
79
## INCLUDE_DIRS: uncomment this if you package contains header files
80
## LIBRARIES: libraries you create in this project that dependent projects also need
81
## CATKIN_DEPENDS: catkin_packages dependent projects also need
82
## DEPENDS: system dependencies of this project that dependent projects also need
83
catkin_package(
84
    INCLUDE_DIRS include
85
    LIBRARIES humotion
86
    #CATKIN_DEPENDS message_runtime
87
    #DEPENDS system_lib
88
)
89

  
90
###########
91
## Build ##
92
###########
93

  
94
## Specify additional locations of header files
95
## Your package locations should be listed before other locations
96
include_directories(BEFORE ${Boost_INCLUDE_DIRS} ${REFLEXXES_INCLUDE_DIRS})
97
include_directories(BEFORE include)
98

  
99
#make sure to use ros messages from current build
100
include_directories(BEFORE ${CATKIN_DEVEL_PREFIX}/include)
101

  
102
#this should be appended:
103
include_directories(${catkin_INCLUDE_DIRS})
104

  
105
#link_directories (${Boost_LIBRARY_DIRS} ${REFLEXXES_LIBRARY_DIRS} ${catkin_LIBRARY_DIRS})
106

  
107
## Declare a cpp library
108
add_library(${PROJECT_NAME}
109
    src/client/client.cpp
110
    src/client/middleware.cpp
111
    src/client/middleware_ros.cpp
112

  
113
    src/server/server.cpp
114
    src/server/config.cpp
115
    src/server/middleware.cpp
116
    src/server/middleware_ros.cpp
117
    src/server/controller.cpp
118
    src/server/joint_interface.cpp
119
    src/server/motion_generator.cpp
120
    src/server/gaze_motion_generator.cpp
121
    src/server/reflexxes_motion_generator.cpp
122
    src/server/mouth_motion_generator.cpp
123
    src/server/eye_motion_generator.cpp
124
    src/server/eyelid_motion_generator.cpp
125
    src/server/eyebrow_motion_generator.cpp
126
    src/server/neck_motion_generator.cpp
127

  
128
    src/mouth_state.cpp
129
    src/gaze_state.cpp
130
    src/timestamp.cpp
131
    src/timestamped_list.cpp
132
)
133

  
134
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
135

  
136
## Add cmake target dependencies of the executable/library
137
## as an example, message headers may need to be generated before nodes
138
add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} ${PROJECT_NAME}_gencpp ${PROJECT_NAME}_gencfg)
139

  
140
## Specify libraries to link a library or executable target against
141
target_link_libraries(${PROJECT_NAME}
142
    ${Boost_LIBRARIES}
143
    ${catkin_LIBRARIES}
144
    ${REFLEXXES_LIBRARY}
145
)
146

  
147
set_property(TARGET ${PROJECT_NAME} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
148

  
149
#############
150
## Install ##
151
#############
152

  
153
# all install targets should use catkin DESTINATION variables
154
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
155

  
156
## Mark executable scripts (Python etc.) for installation
157
## in contrast to setup.py, you can choose the destination
158
# install(PROGRAMS
159
#   scripts/my_python_script
160
#   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
161
# )
162

  
163
## Mark executables and/or libraries for installation
164
install(TARGETS ${PROJECT_NAME}
165
    ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
166
    LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
167
    RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
168
)
169
## Mark cpp header files for installation
170
install(DIRECTORY include/humotion/
171
    DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
172
)
173

  
174
#############
175
## Testing ##
176
#############
177
## Add gtest based cpp test target and link libraries
178
catkin_add_gtest(${PROJECT_NAME}-test-server test/server.cpp)
179
if(TARGET ${PROJECT_NAME}-test-server)
180
target_link_libraries(${PROJECT_NAME}-test-server ${PROJECT_NAME})
181
endif()
182
catkin_add_gtest(${PROJECT_NAME}-test-client test/client.cpp)
183
if(TARGET ${PROJECT_NAME}-test-client)
184
target_link_libraries(${PROJECT_NAME}-test-client ${PROJECT_NAME})
185
endif()
186
catkin_add_gtest(${PROJECT_NAME}-test-timestamp test/timestamp.cpp)
187
if(TARGET ${PROJECT_NAME}-test-timestamp)
188
target_link_libraries(${PROJECT_NAME}-test-timestamp ${PROJECT_NAME})
189
endif()
190

  
191
### Add folders to be run by python nosetests
192
# catkin_add_nosetests(test)
193

  
194

  
195
#finally build (some) examples
196
#add_subdirectory(./examples)
197

  
198

  
199
#################
200
## style guide ##
201
#################
202
set(ENABLE_CPPLINT 1)
203
include(${CMAKE_CURRENT_SOURCE_DIR}/stylecheck/CpplintWrapper.cmake)
204
CPPLINT_RECURSIVE(cpplint_include
205
  ${CMAKE_CURRENT_SOURCE_DIR}/include
206
  ${CMAKE_CURRENT_SOURCE_DIR}/include
207
  ${CMAKE_CURRENT_BINARY_DIR}/include)
208
CPPLINT_RECURSIVE(cpplint_src
209
  ${CMAKE_CURRENT_SOURCE_DIR}/src
210
  ${CMAKE_CURRENT_SOURCE_DIR}/src
211
  ${CMAKE_CURRENT_BINARY_DIR}/src)
212
add_dependencies(${PROJECT_NAME} cpplint_src cpplint_include)
213

  
214
#workaround for qtcreator ide integration. do not remove!
215
file(GLOB_RECURSE NODE_DUMMY_TARGETS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h *.cfg *.yaml *.xml *.launch)
216
add_custom_target(_dummy_target SOURCES ${NODE_DUMMY_TARGETS})
COPYING
1
                   GNU LESSER GENERAL PUBLIC LICENSE
2
                       Version 3, 29 June 2007
3

  
4
 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
 Everyone is permitted to copy and distribute verbatim copies
6
 of this license document, but changing it is not allowed.
7

  
8

  
9
  This version of the GNU Lesser General Public License incorporates
10
the terms and conditions of version 3 of the GNU General Public
11
License, supplemented by the additional permissions listed below.
12

  
13
  0. Additional Definitions.
14

  
15
  As used herein, "this License" refers to version 3 of the GNU Lesser
16
General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
General Public License.
18

  
19
  "The Library" refers to a covered work governed by this License,
20
other than an Application or a Combined Work as defined below.
21

  
22
  An "Application" is any work that makes use of an interface provided
23
by the Library, but which is not otherwise based on the Library.
24
Defining a subclass of a class defined by the Library is deemed a mode
25
of using an interface provided by the Library.
26

  
27
  A "Combined Work" is a work produced by combining or linking an
28
Application with the Library.  The particular version of the Library
29
with which the Combined Work was made is also called the "Linked
30
Version".
31

  
32
  The "Minimal Corresponding Source" for a Combined Work means the
33
Corresponding Source for the Combined Work, excluding any source code
34
for portions of the Combined Work that, considered in isolation, are
35
based on the Application, and not on the Linked Version.
36

  
37
  The "Corresponding Application Code" for a Combined Work means the
38
object code and/or source code for the Application, including any data
39
and utility programs needed for reproducing the Combined Work from the
40
Application, but excluding the System Libraries of the Combined Work.
41

  
42
  1. Exception to Section 3 of the GNU GPL.
43

  
44
  You may convey a covered work under sections 3 and 4 of this License
45
without being bound by section 3 of the GNU GPL.
46

  
47
  2. Conveying Modified Versions.
48

  
49
  If you modify a copy of the Library, and, in your modifications, a
50
facility refers to a function or data to be supplied by an Application
51
that uses the facility (other than as an argument passed when the
52
facility is invoked), then you may convey a copy of the modified
53
version:
54

  
55
   a) under this License, provided that you make a good faith effort to
56
   ensure that, in the event an Application does not supply the
57
   function or data, the facility still operates, and performs
58
   whatever part of its purpose remains meaningful, or
59

  
60
   b) under the GNU GPL, with none of the additional permissions of
61
   this License applicable to that copy.
62

  
63
  3. Object Code Incorporating Material from Library Header Files.
64

  
65
  The object code form of an Application may incorporate material from
66
a header file that is part of the Library.  You may convey such object
67
code under terms of your choice, provided that, if the incorporated
68
material is not limited to numerical parameters, data structure
69
layouts and accessors, or small macros, inline functions and templates
70
(ten or fewer lines in length), you do both of the following:
71

  
72
   a) Give prominent notice with each copy of the object code that the
73
   Library is used in it and that the Library and its use are
74
   covered by this License.
75

  
76
   b) Accompany the object code with a copy of the GNU GPL and this license
77
   document.
78

  
79
  4. Combined Works.
80

  
81
  You may convey a Combined Work under terms of your choice that,
82
taken together, effectively do not restrict modification of the
83
portions of the Library contained in the Combined Work and reverse
84
engineering for debugging such modifications, if you also do each of
85
the following:
86

  
87
   a) Give prominent notice with each copy of the Combined Work that
88
   the Library is used in it and that the Library and its use are
89
   covered by this License.
90

  
91
   b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
   document.
93

  
94
   c) For a Combined Work that displays copyright notices during
95
   execution, include the copyright notice for the Library among
96
   these notices, as well as a reference directing the user to the
97
   copies of the GNU GPL and this license document.
98

  
99
   d) Do one of the following:
100

  
101
       0) Convey the Minimal Corresponding Source under the terms of this
102
       License, and the Corresponding Application Code in a form
103
       suitable for, and under terms that permit, the user to
104
       recombine or relink the Application with a modified version of
105
       the Linked Version to produce a modified Combined Work, in the
106
       manner specified by section 6 of the GNU GPL for conveying
107
       Corresponding Source.
108

  
109
       1) Use a suitable shared library mechanism for linking with the
110
       Library.  A suitable mechanism is one that (a) uses at run time
111
       a copy of the Library already present on the user's computer
112
       system, and (b) will operate properly with a modified version
113
       of the Library that is interface-compatible with the Linked
114
       Version.
115

  
116
   e) Provide Installation Information, but only if you would otherwise
117
   be required to provide such information under section 6 of the
118
   GNU GPL, and only to the extent that such information is
119
   necessary to install and execute a modified version of the
120
   Combined Work produced by recombining or relinking the
121
   Application with a modified version of the Linked Version. (If
122
   you use option 4d0, the Installation Information must accompany
123
   the Minimal Corresponding Source and Corresponding Application
124
   Code. If you use option 4d1, you must provide the Installation
125
   Information in the manner specified by section 6 of the GNU GPL
126
   for conveying Corresponding Source.)
127

  
128
  5. Combined Libraries.
129

  
130
  You may place library facilities that are a work based on the
131
Library side by side in a single library together with other library
132
facilities that are not Applications and are not covered by this
133
License, and convey such a combined library under terms of your
134
choice, if you do both of the following:
135

  
136
   a) Accompany the combined library with a copy of the same work based
137
   on the Library, uncombined with any other library facilities,
138
   conveyed under the terms of this License.
139

  
140
   b) Give prominent notice with the combined library that part of it
141
   is a work based on the Library, and explaining where to find the
142
   accompanying uncombined form of the same work.
143

  
144
  6. Revised Versions of the GNU Lesser General Public License.
145

  
146
  The Free Software Foundation may publish revised and/or new versions
147
of the GNU Lesser General Public License from time to time. Such new
148
versions will be similar in spirit to the present version, but may
149
differ in detail to address new problems or concerns.
150

  
151
  Each version is given a distinguishing version number. If the
152
Library as you received it specifies that a certain numbered version
153
of the GNU Lesser General Public License "or any later version"
154
applies to it, you have the option of following the terms and
155
conditions either of that published version or of any later version
156
published by the Free Software Foundation. If the Library as you
157
received it does not specify a version number of the GNU Lesser
158
General Public License, you may choose any version of the GNU Lesser
159
General Public License ever published by the Free Software Foundation.
160

  
161
  If the Library as you received it specifies that a proxy can decide
162
whether future versions of the GNU Lesser General Public License shall
163
apply, that proxy's public statement of acceptance of any version is
164
permanent authorization for you to choose that version for the
165
Library.
README.md
1 1
# [hu]man [motion] low-level robot ontrol library
2 2

  
3
this is the low level robot control software to allow
4
human like motion generation on a humanoid robotic head
5

  
3
this has been moved to github. see
4
https://github.com/CentralLabFacilities/humotion
cfg/humotion.cfg
1
#!/usr/bin/env python
2
import re
3
PACKAGE = "humotion"
4
from dynamic_reconfigure.parameter_generator_catkin import *
5

  
6
def fetch_default(param_name):
7
    for line in open("../src/server/config.cpp"):
8
        if param_name in line:
9
            result = re.findall("=\s*([\d\w.]+);", line)
10
            print result
11
            if result:
12
                return result[0]
13
            else:
14
                print("ERROR: could not find parameter %s in config.cpp" % (param_name))
15
                sys.exit(1)
16

  
17
def add_entry(group, param_name, descr, min, max):
18
    default_str = fetch_default(param_name)
19
    default_val = float(default_str)
20
    if (default_val > max):
21
        print("ERROR: default value %f for %s exceeds max value (%f)" % (default_val, param_name, max))
22
        sys.exit(1)
23
    if (default_val < min):
24
        print("ERROR: default value %f for %s is under min value (%f)" % (default_val, param_name, min))
25
        sys.exit(1)
26

  
27
    group.add(param_name, double_t, 0, descr, default_val, min, max)
28

  
29
def add_entry_bool(group, param_name, descr):
30
    default = fetch_default(param_name)
31

  
32
    default_val = True
33
    if (default == "false"):
34
        default_val = False
35

  
36
    group.add(param_name, bool_t, 0, descr, default_val)
37

  
38

  
39
gen = ParameterGenerator()
40

  
41
debug_group = gen.add_group("debug")
42
add_entry_bool(debug_group, "publish_internals", "publish debugging data on different topics")
43

  
44
general_group = gen.add_group("thresholds")
45
add_entry(general_group, "threshold_velocity_eye_saccade", "velocity threshold for eye saccade detection (in deg/s)", 1.0, 30.0)
46
add_entry(general_group, "threshold_angle_neck_saccade", "magnitude of gaze change that triggers neck saccade (in deg)", 1.0, 30.0)
47
add_entry(general_group, "threshold_angle_omr_limit", "threshold for a deflection that triggers a correction neck saccade (in percent of OMR)", 0.1, 1.0)
48

  
49
neck_group = gen.add_group("neck")
50
add_entry(neck_group, "scale_velocity_neck", "scaling factor for neck velocity (in percent, 1.0 = full human velocities)", 0.1, 1.0)
51
add_entry(neck_group, "scale_acceleration_neck", "scaling factor for neck acceleration (in percent, 1.0 = full human acceleration)", 0.1, 1.0)
52
add_entry(neck_group, "limit_velocity_neck", "limit for neck velocity (in deg/s)", 100.0, 800.0)
53
add_entry(neck_group, "limit_acceleration_neck", "limit for neck acceleration (in deg/s^2)", 100.0, 10000.0)
54

  
55
eye_group = gen.add_group("eye")
56
add_entry(eye_group, "scale_velocity_eye", "scaling factor for eye velocity (in percent, 1.0 = full human velocities)",  0.1, 1.0)
57
add_entry(eye_group, "scale_acceleration_eye", "scaling factor for eye acceleration (in percent, 1.0 = full human acceleration)", 0.1, 1.0)
58
add_entry(eye_group, "limit_velocity_eye", "limit for eye velocity (in deg/s)", 100.0, 1000.0)
59
add_entry(eye_group, "limit_acceleration_eye", "limit for eye acceleration (in deg/s^2)", 100.0, 80000.0)
60
add_entry_bool(eye_group, "use_neck_target_instead_of_position_eye", "use neck target in difference calc instead of real position")
61

  
62

  
63
eyeblink_group = gen.add_group("eyeblink")
64
add_entry(eyeblink_group, "eyeblink_duration", "duration for an eyeblink (in seconds)", 0.01, 1.0)
65
add_entry(eyeblink_group, "eyeblink_periodic_distribution_lower", "lower bound for probalistic eyeblink distribution (in seconds)", 0.1, 100.0)
66
add_entry(eyeblink_group, "eyeblink_periodic_distribution_upper", "upper bound for probalistic eyeblink distribution (in seconds)", 0.1, 100.0)
67
add_entry(eyeblink_group, "eyeblink_probability_after_saccade", "probability for an eyeblink after a saccade (in percent)", 0.01, 1.0)
68
add_entry(eyeblink_group, "eyeblink_blocked_time", "blocking time for further eyeblinks (in seconds)", 0.1, 100.0)
69

  
70
eyelids_group = gen.add_group("eyelids")
71
add_entry_bool(eyelids_group, "eyelids_follow_eyemotion", "should the eyelids follow the eye tilt motion?")
72

  
73
breath_group = gen.add_group("breath")
74
add_entry(breath_group, "breath_period", "duration for a full breath periond: inhale, pause and exhale (in seconds)", 1.0, 100.0)
75
add_entry(breath_group, "breath_amplitude", "amplitude for breath animation (in deg)", 0.0, 10.0)
76

  
77
exit(gen.generate(PACKAGE, "humotion", "humotion"))
78

  
examples/demo_korg_slider/CMakeLists.txt
1
SET( PROJECT_NAME demo_korg_slider )
2
PROJECT( ${PROJECT_NAME} )
3
# set (CMAKE_VERBOSE_MAKEFILE true)
4
#profiling
5
#set(CMAKE_CXX_FLAGS "-Wall -g -pg")
6
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
7

  
8

  
9
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} /homes/sschulz/src/ros_workspace/install/share/humotion/cmake/)
10
# set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /homes/sschulz/src/ros_workspace/install/lib/pkg_config)
11

  
12
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
13
INCLUDE(FindPkgConfig)
14

  
15
# search for Boost version 1.34
16
find_package( Boost 1.40 COMPONENTS thread program_options system filesystem regex )
17
link_directories ( ${Boost_LIBRARY_DIRS}  )
18
include_directories ( ${Boost_INCLUDE_DIRS} )
19
# message(${Boost_LIBRARIES})
20

  
21

  
22

  
23
SET(PREFIX ${CMAKE_INSTALL_PREFIX})
24
SET(BINDIR "${PREFIX}/bin")
25
SET(INCLUDEDIR "${PREFIX}/include")
26
SET(MANDIR "${PREFIX}/man")
27
SET(LIBDIR "${PREFIX}/lib")
28
SET(DATADIR "${PREFIX}/share/${NAME}")
29

  
30
find_package(humotion 0.0.1)
31
IF (humotion_FOUND)
32
	message("> using humotion includes from " ${humotion_INCLUDE_DIRS})
33
ELSE (humotion_FOUND)
34
	message(FATAL_ERROR "> error: can not find libhumotion")
35
endif (humotion_FOUND)
36

  
37
SET(SRC_FILES
38
	korg_input.cpp
39
)
40

  
41
LINK_DIRECTORIES(${LIBDIR} ${humotion_LIBRARY_DIRS} )
42
INCLUDE_DIRECTORIES( ${humotion_INCLUDE_DIRS} )
43

  
44
ADD_EXECUTABLE( ${PROJECT_NAME} main.cpp ${SRC_FILES})
45
TARGET_LINK_LIBRARIES(  ${PROJECT_NAME} ${Boost_LIBRARIES} ${Boost_LIBS}  ${humotion_LIBRARIES} portmidi porttime) 
46

  
47

  
48
#FILE(GLOB conf_files "${CMAKE_CURRENT_SOURCE_DIR}/*.mcfg")
49
#install (FILES ${conf_files} DESTINATION etc/xsc2)
50

  
51
install (TARGETS ${PROJECT_NAME} DESTINATION bin )
52
set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
53
set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
54

  
examples/demo_korg_slider/korg_input.cpp
1
#include "korg_input.h"
2
#include <assert.h>
3
#include <stdlib.h>
4

  
5
#define DEBUG_SHOW_MIDI_DEVICES 1
6
#define DEBUG_INCOMING_DATA 1
7

  
8
//defines for portmidi
9
#define INPUT_BUFFER_SIZE 100
10
#define OUTPUT_BUFFER_SIZE 0
11
#define DRIVER_INFO NULL
12
#define TIME_PROC ((int32_t (*)(void *)) Pt_Time)
13
#define TIME_INFO NULL
14
#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
15

  
16
//! constructor
17
KorgInput::KorgInput(){
18
	midi = NULL;
19
	//first try old device:
20
	device_open = open_device();
21
	for(int i=0; i<256; i++){
22
		data[i] = 64;
23
		data_new[i] = false;
24
	}
25
}
26

  
27
//! destructor
28
KorgInput::~KorgInput(){
29
	if (device_open){
30
		//close
31
		Pm_Close(midi);
32
	}
33
}
34

  
35
//! fetch device id
36
//! \param char array with device name
37
//! \return id of device, or -1 if not found
38
int KorgInput::fetch_device_id(const char *name, bool output=false){
39
	//fetch device id:
40
	int midi_device_id = -1;
41
	
42
	for (int i = 0; i < Pm_CountDevices(); i++) {
43
		const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
44
		if (DEBUG_SHOW_MIDI_DEVICES) printf("%d: %s, %s\n", i, info->interf, info->name);
45
		
46
		if (output){
47
			if (info->output) {
48
				if (strcmp(info->name, name) == 0){
49
					midi_device_id = i;
50
				}
51
			}
52
		}else{
53
			if (info->input) {
54
				if (strcmp(info->name, name) == 0){
55
					midi_device_id = i;
56
				}
57
			}
58
		}
59
	}
60
	
61
	return midi_device_id;
62
}
63

  
64
//! open device
65
//! \return true if device is found, false otherwise
66
bool KorgInput::open_device(){
67
	PmEvent buffer[1];
68
	
69
	//standard is type1:
70
	device_type = NANO_KONTROL;
71

  
72
	int midi_device_id = fetch_device_id("nanoKONTROL MIDI 1");
73
	int midi_device_id_out = fetch_device_id("nanoKONTROL MIDI 1", true);
74
	if (midi_device_id == -1){
75
		device_type = NANO_KONTROL2;
76
		midi_device_id = fetch_device_id("nanoKONTROL2 MIDI 1");
77
		midi_device_id_out = fetch_device_id("nanoKONTROL2 MIDI 1", true);
78
	}
79
	
80
	
81
	if (midi_device_id == -1){
82
		printf("> can not open device (input). Error: device not found\n");
83
		return false;
84
	}
85
	
86
	if (midi_device_id_out == -1){
87
		printf("> can not open output device\n");
88
		return false;
89
	}
90
	
91
	//success, found device
92
	printf("> found korg controller with id %d (%s)\n",midi_device_id,device_type==NANO_KONTROL?"nanoKONTROL":"nanoKONTROL2");
93
	printf("> if setting leds on/off does not work, make sure to set led mode to external with the korg windows software\n");
94
	
95
	//open input
96
	Pm_OpenInput(&midi, midi_device_id, DRIVER_INFO, INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO);
97
	
98
	//open output
99
	Pm_OpenOutput(&midi_out, midi_device_id_out, DRIVER_INFO, OUTPUT_BUFFER_SIZE, NULL, NULL, 0); 
100
 
101

  
102

  
103

  
104
	//set filter
105
	Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
106
	Pm_SetFilter(midi_out, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
107
	
108
	//clear buffer with unfiltered messages
109
	//printf("> clearing buffer\n");
110
	//while (Pm_Poll(midi)) {
111
		//Pm_Read(midi, buffer, 1);
112
	//}
113
	printf("> init done \n");
114
	
115
	//disable all leds:
116
// 	for(unsigned char id = 0; id<127; id++){
117
// 		Pm_WriteShort(midi_out, TIME_PROC(TIME_INFO), Pm_Message(0xB0, id, 0));
118
// 		usleep(10*1000);
119
// 	}
120
	
121
	//fancy animation:
122
	for(unsigned char id = 0; id<80+4; id++){
123
		if (id<127) Pm_WriteShort(midi_out, TIME_PROC(TIME_INFO), Pm_Message(0xB0, id, 127));
124
		if (id>4)   Pm_WriteShort(midi_out, TIME_PROC(TIME_INFO), Pm_Message(0xB0, id-4, 0));
125
		usleep(25*1000);
126
	}
127
	
128
// 	for(unsigned char id = 0; id<127; id++){
129
// 		Pm_WriteShort(midi_out, TIME_PROC(TIME_INFO), Pm_Message(0xB0, id, 0));
130
// 	}
131
// 	
132
	return true;
133
}
134

  
135
//! device opened sucessfully
136
//! \return true if device is open and working
137
bool KorgInput::device_available(){
138
	return device_open;
139
}
140

  
141

  
142
//! fetch new data
143
//! \return int count how many datasets were fetched
144
int KorgInput::fetch_data(){
145
	int new_data_fetched = 0;
146
	//poll all data:
147
	while(Pm_Poll(midi)){
148
		//new data fetch sucessfull? build up dataset:
149
		if (fetch_single()){
150
			new_data_fetched++;
151
		}
152
	}
153

  
154
	if (new_data_fetched > 0){
155
		printf("> fetched %d datasets\n",new_data_fetched);
156
	}
157
	
158
	return new_data_fetched;
159
}
160

  
161
bool KorgInput::fetch_single(){
162
	PmEvent buffer[1];
163
	
164
	//poll data:
165
	PmError status = Pm_Poll(midi);
166
	
167
	if (status) {
168
		int length = Pm_Read(midi,buffer, 1);
169
		if (length > 0) {
170
			//store incoming data:
171
			if (Pm_MessageStatus(buffer[0].message) == 0xb0){
172
				unsigned int idx = Pm_MessageData1(buffer[0].message) & 0xFF;
173
				data[idx] = Pm_MessageData2(buffer[0].message) & 0xFF;
174
				data_new[idx] = true;
175
			}
176
			
177
			if (DEBUG_INCOMING_DATA){
178
				printf("> incoming message: time %ld, %2lx %2lx %2lx\n",
179
					(long) buffer[0].timestamp,
180
					(long) Pm_MessageStatus(buffer[0].message),
181
					(long) Pm_MessageData1(buffer[0].message),
182
					(long) Pm_MessageData2(buffer[0].message));
183
			}
184
			
185
			return true;
186
		} else {
187
			printf("> error, message len <= 0?!\n");
188
			return false;
189
		}
190
	}
191
	
192
}
193

  
194
//! access buffered data
195
//! \param index of data channel to fetch
196
//! \return unsigned char value for data channel <index> (0..127)
197
unsigned char KorgInput::get_buffered_raw_value(unsigned char index){
198
	return data[index];
199
}
200

  
201
//! fetch a value + new flag & clear
202
//! \param idx index
203
//! \param uchar ptr to data
204
//! \return true if new data available
205
bool KorgInput::get_and_reset(unsigned char idx, unsigned char *val){
206
	//fetch state & reset:
207
	bool new_data = data_new[idx];
208
	data_new[idx] = false;
209
	
210
	//override data only if new val arrived:
211
	if (new_data){
212
		*val = get_buffered_raw_value(idx);
213
	}	
214
	
215
	return new_data;
216
}
217

  
218
//! access slider 
219
//! \param slider index 0..8
220
//! \param uchar ptr to value
221
//! \return bool if new value arrived
222
bool KorgInput::get_slider(unsigned char index, unsigned char *val){
223
	assert(index <= 8);
224
	if (device_type == NANO_KONTROL){
225
		switch(index){
226
			default: 
227
				
228
				return get_and_reset(0x02 + index, val);
229
			case(5):
230
			case(6):
231
				return get_and_reset(0x02 + index + 1, val);
232
			case(7):
233
			case(8):
234
				return get_and_reset(0x02 + index + 3, val);
235
		}
236
	}else{
237
		//NANO_KONTROL2
238
		return get_and_reset(index, val);
239
	}
240
}
241

  
242
//! access button 
243
//! \param button index 
244
//! \param uchar ptr to value
245
//! \return bool if new value arrived
246
bool KorgInput::get_button(unsigned char index, unsigned char *val){
247
	assert(index <= 127);
248
	
249
	if (device_type == NANO_KONTROL){
250
		printf("> NANO_KONTROL NOT SUPPORTED, different layout of buttons! exiting\n");
251
		exit(1);
252
		/*if (row == 0){
253
			return get_and_reset(0x17+index, val);
254
		}else if (row == 1){
255
			printf("> NANO_KONTROL does not have center row. ignored\n");
256
			return false;
257
		}else{
258
			return get_and_reset(0x21+index, val);
259
		}*/
260
	}else{
261
		//NANO_KONTROL2 - fetch button value
262
		return get_and_reset(index, val);
263
	}
264
}
265

  
266
//! access pot 
267
//! \param pot index 0..8
268
//! \param unsigned char ptr to value (0..127)
269
//! \param bool true if new data available
270
bool KorgInput::get_pot(unsigned char index, unsigned char *val){
271
	assert(index <= 8);
272
	if (device_type == NANO_KONTROL){
273
		return get_and_reset(0x0E + index, val);
274
	}else{
275
		//NANO_KONTROL2
276
		return get_and_reset(0x10 + index, val);
277
	}
278
}
279

  
280
void  KorgInput::set_led(unsigned char index, bool status){
281
	Pm_WriteShort(midi_out, TIME_PROC(TIME_INFO), Pm_Message(0xB0, index, status?127:0));
282
}
examples/demo_korg_slider/korg_input.h
1
#pragma once
2

  
3
#include <portmidi.h>
4
#include <porttime.h>
5
#include <cstdio>
6
#include <stdio.h>
7
#include <string.h>
8
#include <unistd.h>
9

  
10
class KorgInput{
11
public:
12
	KorgInput();
13
	~KorgInput();
14
	
15
	bool  get_slider(unsigned char index, unsigned char *val);
16
	bool  get_pot(unsigned char index, unsigned char *val);
17
	bool  get_button(unsigned char index, unsigned char *val);
18
	void  set_led(unsigned char index, bool status);
19
	
20
	bool get_and_reset(unsigned char idx, unsigned char *val);
21
	void set_pot(unsigned char index, int value);
22
	
23
	int  fetch_data();
24
	bool device_available();
25
	
26
	
27
private:
28
	int resolve_id();
29
	
30
	unsigned char data[256];
31
	bool data_new[256];
32
	int device_type;
33
	enum DEVICE_TYPE {NANO_KONTROL, NANO_KONTROL2};
34
	bool open_device();
35
	bool fetch_single();
36
	int fetch_device_id(const char*, bool);
37
	unsigned char get_buffered_raw_value(unsigned char index);
38
	
39
	bool device_open;
40
	PmStream * midi;
41
	PmStream * midi_out;
42
};
examples/demo_korg_slider/main.cpp
1
#include <cstdio>
2
#include <stdio.h>
3
#include <string.h>
4

  
5

  
6
#include "korg_input.h"
7
#include "humotion/client/client.h"
8
#include "boost/date_time/posix_time/posix_time.hpp"
9
#include <boost/thread/thread_time.hpp>
10
#include <boost/thread/thread.hpp>
11

  
12
using namespace boost;
13
humotion::GazeState last_awake_state;
14
bool awake_state;
15

  
16
enum JOINT_SLIDER_ID{
17
	MOUTH_POSITION_LEFT=0,
18
	MOUTH_POSITION_CENTER,
19
	MOUTH_POSITION_RIGHT,
20
	PAN,
21
	TILT
22
	//NECK_ROLL,
23
};
24

  
25
enum JOINT_POTI_ID{
26
	MOUTH_OPENING_LEFT=0,
27
	MOUTH_OPENING_CENTER,
28
	MOUTH_OPENING_RIGHT,
29
	EYE_VERGENCE,
30
	EYELID_OPENING_UPPER,
31
	EYELID_OPENING_LOWER,
32
	EYEBROW_RIGHT,
33
	EYEBROW_LEFT
34
};
35

  
36

  
37

  
38
float to_float(unsigned char val){
39
	return ((float)(val))/127.0;
40
}
41

  
42
void slidervalues_to_mouthstate(KorgInput *input, humotion::MouthState *result){
43
	unsigned char tmp;
44
	
45
	//do not handle updates when not awake
46
	if (!awake_state){
47
		return;
48
	}
49
	
50
	if (input->get_slider(MOUTH_POSITION_LEFT,  &tmp))result->position_left   = 0.0 + 40.0 * (1.0-to_float(tmp));
51
	if (input->get_slider(MOUTH_POSITION_CENTER,  &tmp))result->position_center = 0.0 + 40.0 * (1.0-to_float(tmp));
52
	if (input->get_slider(MOUTH_POSITION_RIGHT,  &tmp))result->position_right  = 0.0 + 40.0 * (1.0-to_float(tmp));
53

  
54
	if (input->get_pot(MOUTH_OPENING_LEFT,  &tmp)) result->opening_left   = 40.0 * to_float(tmp);
55
	if (input->get_pot(MOUTH_OPENING_CENTER,  &tmp)) result->opening_center= 40.0 * to_float(tmp);
56
	if (input->get_pot(MOUTH_OPENING_RIGHT,  &tmp)) result->opening_right  = 40.0 * to_float(tmp);
57

  
58
	//printf("OOO %4.2f %4.2f\n",result.opening_center, result.position_center);
59
}
60

  
61
void wake_up(humotion::GazeState *result){
62
	if (awake_state){
63
		//already awake, return
64
		return;
65
	}
66
	
67
	//restore last awake state
68
	*result = last_awake_state;
69
	//force reopening
70
	result->eyeblink_request_left  = 10;
71
	result->eyeblink_request_right = 10;
72
	
73
	awake_state = true;
74
}
75

  
76
void sleep(humotion::GazeState *result){
77
	if (!awake_state){
78
		//already sleeping, return
79
		return;
80
	}
81
	
82
	//store last awake state
83
	last_awake_state = *result;
84
	awake_state = false;
85
	
86
	//override values:
87
	result->pan  = 0.0;
88
	result->tilt = -20.0;
89
	result->roll = 0.0;
90
	
91
	//result->eyelid_opening = 0.0;
92
	result->eyebrow_left  = 0.0;
93
	result->eyebrow_right = 0.0;
94
	
95
	result->eyeblink_request_left = -1;
96
	result->eyeblink_request_right = -1;
97
	
98
	
99
}
100

  
101
void slidervalues_to_gazestate(KorgInput *input, humotion::GazeState *result){
102
	unsigned char tmp;
103
	
104
	//PLAY
105
	if (input->get_button(0x29, &tmp)){
106
		if (tmp != 0){
107
			wake_up(result);
108
		}
109
	}
110
	
111
	//STOP
112
	if (input->get_button(0x2A, &tmp)){
113
		if (tmp != 0){
114
			sleep(result);
115
		}
116
	}
117
	
118
	//do not handle updates when not awake
119
	if (!awake_state){
120
		return;
121
	}
122
	
123
	if (input->get_slider(PAN,  &tmp)) result->pan  = -50.0 + 100.0 * to_float(tmp);
124
	if (input->get_slider(TILT, &tmp)) result->tilt = -40.0 + 80.0 * to_float(tmp);
125
	result->roll = 0.0;
126
	
127
	if (input->get_pot(EYELID_OPENING_UPPER, &tmp)) result->eyelid_opening_upper = 0.0 + 120.0*to_float(tmp);
128
	if (input->get_pot(EYELID_OPENING_LOWER, &tmp)) result->eyelid_opening_lower = 0.0 + 120.0*to_float(tmp);
129

  
130
	
131
	if (input->get_pot(EYEBROW_LEFT,  &tmp)) result->eyebrow_left  = 60.0 - 120.0*to_float(tmp);
132
	if (input->get_pot(EYEBROW_RIGHT,  &tmp)) result->eyebrow_right = 60.0 - 120.0*to_float(tmp);
133
	
134
	if (input->get_pot(EYE_VERGENCE,  &tmp)) result->vergence = -20.0 * to_float(tmp);
135
	
136
	
137
	//check for blink requests: 
138
	if (input->get_button(0x24, &tmp)){
139
		if (tmp != 0){
140
			//blink left
141
			result->eyeblink_request_left = 300;
142
		}
143
	}
144
	if (input->get_button(0x44, &tmp)){
145
		if (tmp != 0){
146
			result->eyeblink_request_right = 300;
147
		}
148
	}
149
	if (input->get_button(0x34, &tmp)){
150
		if (tmp != 0){
151
			//blink both
152
			result->eyeblink_request_right = 150;
153
			result->eyeblink_request_left  = 150;
154
		}
155
	}
156
	
157
	//printf("PTR = %3.1f %3.1f %3.1f\n",result->pan,result->tilt,result->roll);
158
}
159

  
160
int main(int argc, char **argv){
161
	humotion::MouthState mouth_state;
162
	humotion::GazeState gaze_state;
163
	awake_state = true;
164
	
165
	if (argc != 2){
166
		printf("> ERROR: invalid parameter count.\n\nusage: %s <scope>\n       (e.g. %s /flobi)\n\n",argv[0],argv[0]);
167
		exit(EXIT_FAILURE);
168
	}
169

  
170
	printf("> starting korg kontrol demo. please make sure the korg device is connected via usb\n");
171
	
172
	KorgInput *kinput = new KorgInput();
173
	
174
	if (!kinput->device_available()){
175
		printf("> no korg kontrol device found on usb bus... exiting\n");
176
		return 0;
177
	}
178
	
179
	//set led status for blink requests:
180
	kinput->set_led(0x24, true);
181
	kinput->set_led(0x34, true);
182
	kinput->set_led(0x44, true);
183
	
184
	//set led for stop/play
185
	kinput->set_led(0x29, true);
186
	kinput->set_led(0x2A, true);
187
	
188
	
189
	//human motion connection:
190
	humotion::client::Client *client = new humotion::client::Client(argv[1], "ROS");
191
	
192
	//send values to human motion server
193
	float loop_delay = 1000.0 / 50.0; //run with 50Hz
194
	
195
	boost::system_time timeout = get_system_time() + posix_time::milliseconds(loop_delay);
196
	
197
	while(client->ok()){
198
		//allow middleware to process data
199
		client->tick();
200
		
201
		//clear previous eyeblinks
202
		gaze_state.eyeblink_request_left  = 0;
203
		gaze_state.eyeblink_request_right = 0;
204
	
205
		//handle slider data
206
		if (kinput->fetch_data() > 0){
207
			//debug
208
			mouth_state.dump();
209
			gaze_state.dump();
210
			printf("\n");
211

  
212
			//transfer values to robot:
213
			slidervalues_to_mouthstate(kinput, &mouth_state);
214
			slidervalues_to_gazestate(kinput, &gaze_state);
215
		} 
216
		
217
		//printf("BLINK: %d %d\n",gaze_state.eyeblink_request_left, gaze_state.eyeblink_request_right);
218
		
219
		//periodically send mouth & gaze target
220
		client->update_mouth_target(mouth_state);
221
		client->update_gaze_target(gaze_state);
222
		client->send_all();
223
		
224
		thread::sleep(timeout);
225
		timeout = get_system_time() + posix_time::milliseconds(loop_delay);
226

  
227
	}
228
	
229
}
examples/meka/CMakeLists.txt
1
PROJECT(meka_humotion_server)
2
cmake_minimum_required(VERSION 2.8)
3
SET(MAIN ${PROJECT_NAME})
4

  
5
set(ENV{ROS_LANG_DISABLE} "genjava")
6
set(ROS_BUILD_TYPE Debug)
7

  
8
################################################################
9
# check for ROS support:
10
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs sensor_msgs message_generation genmsg)
11
IF (catkin_FOUND)
12
    set(ROS_FOUND 1)
13
    message(STATUS "ROS Support is ON")
14
    add_definitions(-DROS_SUPPORT=1)
15
ENDIF (catkin_FOUND)
16

  
17
IF (NOT catkin_FOUND)
18
  message(FATAL_ERROR "Error: could not find ROS!")
19
ENDIF ()
20

  
21
FIND_PACKAGE(Boost REQUIRED COMPONENTS system thread)
22
FIND_PACKAGE(humotion REQUIRED)
23

  
24
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
25
#add_message_files(
26
#    FILES
27
#)
28

  
29
#generate_messages(
30
#    DEPENDENCIES
31
#    std_msgs
32
#)
33

  
34
#hack to allow sub dir calls work
35

  
36
catkin_package(
37
    INCLUDE_DIRS include
38
    LIBRARIES humotion
39
    #CATKIN_DEPENDS message_runtime
40
    #DEPENDS system_lib
41
)
42

  
43
include_directories( ${catkin_INCLUDE_DIRS})
44

  
45
# add include directories
46
INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS} ${ICUB_INCLUDE_DIRS} ${humotion_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} include/)
47
link_directories(${Boost_LIBRARY_DIRS} ${humotion_LIBRARY_DIRS})
48

  
49
# add required linker flags
50

  
51
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ICUB_LINK_FLAGS}")
52
file(GLOB DUMMY_HEADER_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/*.h)
53

  
54
#add_dependencies(${MAIN} ${catkin_EXPORTED_TARGETS})
55
ADD_EXECUTABLE(${MAIN} src/main.cpp src/mekajointinterface.cpp ${DUMMY_HEADER_LIST})
56

  
57
TARGET_LINK_LIBRARIES(${MAIN} ${Boost_LIBRARIES} ${catkin_LIBRARIES} ${humotion_LIBRARIES})
58
set_property(TARGET ${MAIN} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
59

  
60

  
61
#INSTALL(TARGETS ${MAIN} DESTINATION bin)
62
install(TARGETS ${MAIN}
63
    ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
64
    LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
65
    RUNTIME DESTINATION bin 
66
)
67

  
examples/meka/include/mekajointinterface.h
1
#pragma once
2
#include <humotion/server/joint_interface.h>
3
#include <humotion/server/server.h>
4
#include <boost/bimap.hpp>
5

  
6
#include "ros/ros.h"
7
#include "sensor_msgs/JointState.h"
8
#include "trajectory_msgs/JointTrajectory.h"
9

  
10
#include <m3meka_msgs/M3ControlStates.h>
11

  
12
class MekaJointInterface : public humotion::server::JointInterface{
13
public:
14
    MekaJointInterface(std::string _input_scope, std::string control_scope, std::string _output_scope);
15
    ~MekaJointInterface();
16

  
17
    //void fetch_position(Device *dev, double timestamp);
18
    //void fetch_speed(Device *dev, double timestamp);
19
    //void fetch_position(int id, double value, double timestamp);
20
    //void fetch_speed(int id, double value, double timestamp);
21
    void run();
22

  
23
    static const int MAIN_LOOP_FREQUENCY = 50;
24

  
25
protected:
26
    void disable_joint(int e);
27
    void publish_target(int e, float position, float velocity);
28
    void enable_joint(int e);
29
    void execute_motion();
30

  
31
private:
32
    void incoming_controlstate(const m3meka_msgs::M3ControlStates &control_state);
33
    void incoming_jointstates(const sensor_msgs::JointState & msg);
34
    void store_dummy_data(int id, humotion::Timestamp timestamp);
35
    void store_min_max(int id, float min, float max);
36
    ros::Subscriber joint_state_subscriber;
37
    ros::Subscriber control_state_subscriber;
38
    ros::Publisher target_publisher;
39

  
40
    void set_eyelid_angle(double angle);
41
    void set_eyebrow_angle(int id);
42
    void set_mouth();
43

  
44
    //iCubDataReceiver *icub_data_receiver;
45
    void init_joints();
46
    double lid_angle;
47
    int lid_opening_previous;
48
    int previous_mouth_state;
49

  
50
    std::string input_scope;
51
    std::string control_scope;
52
    std::string output_scope;
53

  
54
    float last_pos_eye_vergence;
55
    float last_pos_eye_pan;
56
    float last_vel_eye_vergence;
57
    float last_vel_eye_pan;
58

  
59
    bool controller_enabled;
60

  
61
    void store_joint(int id, float value);
62
    void set_target_in_positionmode(int id, double value);
63
    void set_target_in_velocitymode(int id, double value);
64

  
65

  
66
    int convert_enum_to_motorid(int e);
67
    int convert_motorid_to_enum(int id);
68

  
69

  
70
    typedef boost::bimap<int, int > enum_id_bimap_t;
71
    typedef enum_id_bimap_t::value_type enum_id_bimap_entry_t;
72
    enum_id_bimap_t enum_id_bimap;
73
};
examples/meka/package.xml
1
<?xml version="1.0"?>
2
<package>
3
  <name>meka_humotion_server</name>
4
  <version>0.0.1</version>
5
  <description>humotion server for the mekabot</description>
6

  
7
  <!-- One maintainer tag required, multiple allowed, one person per tag --> 
8
  <maintainer email="sschulz@todo.todo">Simon Schulz</maintainer>
9

  
10

  
11
  <!-- One license tag required, multiple allowed, one license per tag -->
12
  <!-- Commonly used license strings: -->
13
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
14
  <license>TODO</license>
15

  
16

  
17
  <!-- Url tags are optional, but mutiple are allowed, one per tag -->
18
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
19
  <!-- Example: -->
20
  <url type="website">https://projects.cit-ec.uni-bielefeld.de/git/flobidev.core.git</url> -->
21

  
22

  
23
  <!-- Author tags are optional, mutiple are allowed, one per tag -->
24
  <!-- Authors do not have to be maintianers, but could be -->
25
  <!-- Example: -->
26
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->
27

  
28

  
29
  <!-- The *_depend tags are used to specify dependencies -->
30
  <!-- Dependencies can be catkin packages or system dependencies -->
31
  <!-- Examples: -->
32
  <!-- Use build_depend for packages you need at compile time: -->
33
  <!-- Use buildtool_depend for build tool packages: -->
34
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
35
  <!-- Use run_depend for packages you need at runtime: -->
36
  <!-- <run_depend>message_runtime</run_depend> -->
37
  <!-- Use test_depend for packages you need only for testing: -->
38
  <!--   <test_depend>gtest</test_depend> -->
39
  <buildtool_depend>catkin</buildtool_depend>
40
  <build_depend>roscpp</build_depend>
41
  <build_depend>std_msgs</build_depend>
42
  <!-- <run_depend>roscpp</run_depend> -->
43
  <!-- <run_depend>std_msgs</run_depend> -->
44

  
45
  <!--<build_depend>actionlib</build_depend>
46
  <build_depend>actionlib_msgs</build_depend>
47
  <run_depend>actionlib</run_depend> -->
48
  <!-- <run_depend>actionlib_msgs</run_depend> -->
49

  
50
  <!-- The export tag contains other, unspecified, tags -->
51
  <export>
52
    <!-- You can specify that this package is a metapackage here: -->
53
    <!-- <metapackage/> -->
54

  
55
    <!-- Other tools can request additional information be placed here -->
56

  
57
  </export>
58
</package>
examples/meka/src/main.cpp
1
#include <stdio.h>
2
#include <humotion/server/server.h>
3
#include <string>
4
#include <iostream>
5
//#include "meka_data_receiver.h"
6
#include "mekajointinterface.h"
7

  
8
using namespace std;
9

  
10
int main(int argc, char *argv[]){
11
    /*Property params;
12
    params.fromCommand(argc, argv);
13

  
14
    if (!params.check("robot")){
15
        fprintf(stderr, "Please specify the name of the robot\n");
16
        fprintf(stderr, "--robot name (e.g. icub or icubSim)\n");
17
        return -1;
18
    }
19

  
20
    string robotName=params.find("robot").asString().c_str();
21
    string scope="/"+robotName;
22

  
23
*/
24

  
25
    if (argc != 5){
26
        printf("> ERROR: invalid number of parameters passed to server!\n\n");
27
        printf("usage   : %s <humotion base topic> <jointstates topic> <controlstates topic> <control output topic>\n\n",argv[0]);
28
        printf("example : %s /meka /joint_states  /meka_roscontrol_state_manager/state /meka_roscontrol/head_position_trajectory_controller/command)\n\n",argv[0]);
29
        exit(EXIT_FAILURE);
30
    }
31

  
32
    //create humotion interface
33
    string humotion_scope      = argv[1];
34
    string jointstates_scope   = argv[2];
35
    string controlstates_scope = argv[3];
36
    string control_scope       = argv[4];
37

  
38

  
39
    MekaJointInterface *jointinterface = new MekaJointInterface(jointstates_scope, controlstates_scope, control_scope);
40
    humotion::server::Server *humotion_server = new humotion::server::Server(humotion_scope, "ROS", jointinterface);
41

  
42
    //finally run it
43
    jointinterface->run();
44

  
45
    while(humotion_server->ok()){
46
        usleep(100000);
47
    }
48

  
49
    printf("> ros connection died, will exit now\n");
50

  
51
    return 0;
52
}
examples/meka/src/mekajointinterface.cpp
1
#include "mekajointinterface.h"
2

  
3
using std::cout;
4
using std::cerr;
5

  
6
using humotion::Timestamp;
7

  
8
//WARNING: DO NOT CHANGE THIS; VELOCITYMODE IS NOT YET IMPLEMENTED
9
#define POSITION_CONTROL 1
10

  
11
void MekaJointInterface::incoming_controlstate(const m3meka_msgs::M3ControlStates &control_state){
12
    //incoming controller status
13
    for (unsigned int i = 0; i<control_state.group_name.size(); i++){
14
        if (control_state.group_name[i] == "head"){
15
            //enable/disable based on controller status
16
            if (control_state.state[i] == m3meka_msgs::M3ControlStates::START){
17
                //controller up and running
18
                if (!controller_enabled){
19
                    printf("> incoming control state (%d), enabling jointstate output\n",control_state.state[i]);
20
                    controller_enabled = true;
21
                }
22
            }else{
23
                //controller in estop/stopped etc
24
                if (controller_enabled){
25
                    printf("> incoming control state (%d), DISABLING jointstate output\n",control_state.state[i]);
26
                    controller_enabled = false;
27
                }
28
            }
29
        }
30
    }
31
}
32

  
33
void MekaJointInterface::incoming_jointstates(const sensor_msgs::JointState & msg){
34
    //fetch current timestamp
35
    Timestamp timestamp = Timestamp(msg.header.stamp.toSec());
36

  
37
    //iterate through incoming joints and filter out joints we need:
38
    for(int i=0; i<msg.name.size(); i++){
39

  
40
        std::string name = msg.name[i];
41
        //printf("incoming data for joint '%s'\n", name.c_str());
42

  
43
        int id = -1;
44
        if (name == "head_j1"){
45
            id = ID_NECK_PAN;
46
        }else if(name == "head_j0"){
47
            id = ID_NECK_TILT;
48
        }
49

  
50
        //store data:
51
        if (id != -1){
52
            //printf("> storing joint data for joint id %d\n", id);
53
            if (i >= msg.position.size()){
54
                printf("> joint state msg is missing position data for joint '%s'...\n", name.c_str());
55
                return;
56
            }
57
            if (i >= msg.velocity.size()){
58
                //printf("> joint state msg is missing velocity data for joint '%s'...\n", name.c_str());
59
                //exit(EXIT_FAILURE);
60
                return;
61
            }
62
            //ok, safe to access data
63
            if (id == ID_NECK_PAN){
64
                //joint is inverted
65
                JointInterface::store_incoming_position(id, -180.0 / M_PI * msg.position[i], timestamp);
66
                JointInterface::store_incoming_velocity(id, -180.0 / M_PI * msg.velocity[i], timestamp);
67
            }else if (id == ID_NECK_TILT){
68
                JointInterface::store_incoming_position(id, 180.0 / M_PI * msg.position[i], timestamp);
69
                JointInterface::store_incoming_velocity(id, 180.0 / M_PI * msg.velocity[i], timestamp);
70
            }
71
        }
72
    }
73

  
74
    //dummy data uses current time
75
    timestamp = Timestamp::now();
76

  
77
    //store dummy positions for joints we do not know about:
78
    store_dummy_data(ID_LIP_LEFT_UPPER, timestamp);
79
    store_dummy_data(ID_LIP_LEFT_LOWER, timestamp);
80
    store_dummy_data(ID_LIP_CENTER_UPPER, timestamp);
81
    store_dummy_data(ID_LIP_CENTER_LOWER, timestamp);
82
    store_dummy_data(ID_LIP_RIGHT_UPPER, timestamp);
83
    store_dummy_data(ID_LIP_RIGHT_LOWER, timestamp);
84

  
85
    store_dummy_data(ID_NECK_ROLL, timestamp);
86
    store_dummy_data(ID_EYES_BOTH_UD, timestamp);
87
    store_dummy_data(ID_EYES_LEFT_LR, timestamp);
88
    store_dummy_data(ID_EYES_RIGHT_LR, timestamp);
89
    store_dummy_data(ID_EYES_LEFT_LID_LOWER, timestamp);
90
    store_dummy_data(ID_EYES_LEFT_LID_UPPER, timestamp);
91
    store_dummy_data(ID_EYES_LEFT_BROW, timestamp);
92
    store_dummy_data(ID_EYES_RIGHT_LID_LOWER, timestamp);
93
    store_dummy_data(ID_EYES_RIGHT_LID_UPPER, timestamp);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff