Statistics
| Branch: | Tag: | Revision:

humotion / examples / meka / src / mekajointinterface.cpp @ b1bbdb26

History | View | Annotate | Download (7.524 KB)

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);
94
    store_dummy_data(ID_EYES_RIGHT_BROW, timestamp);
95

    
96
}
97

    
98
void MekaJointInterface::store_dummy_data(int id, Timestamp timestamp){
99
    JointInterface::store_incoming_position(id, 0.0, timestamp);
100
    JointInterface::store_incoming_velocity(id, 0.0, timestamp);
101
}
102

    
103
//! constructor
104
MekaJointInterface::MekaJointInterface(std::string _input_scope, std::string control_scope, std::string _output_scope) : humotion::server::JointInterface(){
105
    input_scope = _input_scope;
106
    output_scope = _output_scope;
107

    
108
    controller_enabled = false;
109

    
110
    //subscribe to meka joint states
111
    int argc = 0;
112
    ros::init(argc, (char**)NULL, "meka_humotion");
113
    ros::NodeHandle n;
114

    
115
    printf("> listening on jointstates on '%s'\n",input_scope.c_str());
116
    joint_state_subscriber = n.subscribe(input_scope, 150, &MekaJointInterface::incoming_jointstates, this);
117

    
118
    printf("> listening on controlstates on '%s'\n",control_scope.c_str());
119
    control_state_subscriber = n.subscribe(control_scope, 150, &MekaJointInterface::incoming_controlstate, this);
120

    
121
    printf("> sending targets on '%s'\n", output_scope.c_str());
122
    target_publisher = n.advertise<trajectory_msgs::JointTrajectory>(output_scope, 100);
123

    
124
    //tell humotion about min/max joint values:
125
    init_joints();
126
}
127

    
128
//! destructor
129
MekaJointInterface::~MekaJointInterface(){
130
}
131

    
132

    
133

    
134
void MekaJointInterface::run(){
135
   ros::spin();
136
}
137

    
138
//! set the target position of a joint
139
//! \param enum id of joint
140
//! \param float value
141
void MekaJointInterface::publish_target(int e, float position, float velocity){
142
   //we do this in execute motion for all joints at once...
143
}
144

    
145

    
146
//! actually execute the scheduled motion commands
147
void MekaJointInterface::execute_motion(){
148
    if (controller_enabled){
149
        //build msg
150
        trajectory_msgs::JointTrajectory msg;
151
        msg.joint_names.push_back("head_j0");
152
        msg.joint_names.push_back("head_j1");
153

    
154
        trajectory_msgs::JointTrajectoryPoint p;
155
        p.positions.push_back(get_target_position(ID_NECK_TILT) * M_PI / 180.0);
156
        //pan joint is inverted!
157
        p.positions.push_back(-get_target_position(ID_NECK_PAN) * M_PI / 180.0);
158
        //printf("targets pan=%4.1f tilt=%4.1f (eye p %4.1f t %4.2f)\n",joint_target[ID_NECK_TILT],joint_target[ID_NECK_PAN],joint_target[ID_EYES_LEFT_LR],joint_target[ID_EYES_BOTH_UD]);
159

    
160
        p.time_from_start = ros::Duration(1.2 * 1.0 / humotion::server::Server::MOTION_UPDATERATE);
161

    
162
        msg.points.push_back(p);
163

    
164
        target_publisher.publish(msg);
165
    }
166
}
167

    
168

    
169
//! prepare and enable a joint
170
//! NOTE: this should also prefill the min/max positions for this joint
171
//! \param the enum id of a joint
172
void MekaJointInterface::enable_joint(int e){
173
    //meka does not support this, joints are always enabled
174
}
175

    
176
//! shutdown and disable a joint
177
//! \param the enum id of a joint
178
void MekaJointInterface::disable_joint(int e){
179
    //meka does not support this, joints are always enabled
180
}
181

    
182
void MekaJointInterface::store_min_max(int id, float min, float max){
183
    joint_min[id] = min;
184
    joint_max[id] = max;
185
}
186

    
187
void MekaJointInterface::init_joints(){
188
    store_min_max(ID_NECK_TILT, -37, 1);
189
    store_min_max(ID_NECK_PAN, -70, 70);
190

    
191
    store_min_max(ID_NECK_ROLL, -1, 1);
192
    store_min_max(ID_EYES_BOTH_UD, -1, 1);
193
    store_min_max(ID_EYES_LEFT_LR, -1, 1);
194
    store_min_max(ID_EYES_RIGHT_LR, -1, 1);
195
    store_min_max(ID_EYES_LEFT_LID_UPPER, -1, 1);
196
    store_min_max(ID_EYES_LEFT_LID_LOWER, -1, 1);
197
    store_min_max(ID_EYES_RIGHT_LID_UPPER, -1, 1);
198
    store_min_max(ID_EYES_RIGHT_LID_LOWER, -1, 1);
199
    store_min_max(ID_EYES_LEFT_BROW, -1, 1);
200
    store_min_max(ID_EYES_RIGHT_BROW, -1, 1);
201
    store_min_max(ID_LIP_CENTER_UPPER, -1, 1);
202
    store_min_max(ID_LIP_CENTER_LOWER, -1, 1);
203
    store_min_max(ID_LIP_LEFT_UPPER, -1, 1);
204
    store_min_max(ID_LIP_LEFT_LOWER, -1, 1);
205
    store_min_max(ID_LIP_RIGHT_UPPER, -1, 1);
206
    store_min_max(ID_LIP_RIGHT_LOWER, -1, 1);
207
}
208