forked from jhu-lcsr/rtt_gazebo
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdefault_gazebo_component.cpp
226 lines (183 loc) · 6.82 KB
/
default_gazebo_component.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/common.hh>
#include <kdl/jntarray.hpp>
#include <kdl/jntarrayvel.hpp>
#include <rtt/Component.hpp>
#include <rtt/Port.hpp>
#include <rtt/TaskContext.hpp>
#include <rtt/Logger.hpp>
class DefaultGazeboComponent : public RTT::TaskContext
{
public:
enum CommandType {
EFFORT,
VELOCITY,
POSITION
};
DefaultGazeboComponent(std::string const& name) :
RTT::TaskContext(name),
kp_(1.0),
kd_(0.1),
steps_rtt_(0),
steps_gz_(0),
n_joints_(0)
{
// Add required gazebo interfaces
this->provides("gazebo")->addOperation("configure",&DefaultGazeboComponent::gazeboConfigureHook,this,RTT::ClientThread);
this->provides("gazebo")->addOperation("update",&DefaultGazeboComponent::gazeboUpdateHook,this,RTT::ClientThread);
this->provides("joint_state")->addPort("names", port_state_names);
this->provides("joint_state")->addPort("posvel", port_state_posvel);
this->provides("joint_state")->addPort("effort", port_state_effort);
this->provides("joint_command")->addPort("position", port_cmd_position);
this->provides("joint_command")->addPort("velocity", port_cmd_velocity);
this->provides("joint_command")->addPort("effort", port_cmd_effort);
this->provides("debug")->addAttribute("time_wall",wall_time_);
this->provides("debug")->addAttribute("time_rtt",rtt_time_);
this->provides("debug")->addAttribute("time_gz",gz_time_);
this->provides("debug")->addAttribute("period_sim",period_sim_);
this->provides("debug")->addAttribute("period_wall",period_wall_);
this->provides("debug")->addAttribute("steps_rtt",steps_rtt_);
this->provides("debug")->addAttribute("steps_gz",steps_gz_);
this->provides("debug")->addAttribute("n_joints",n_joints_);
this->provides("debug")->addAttribute("joint_pos",state_pos_);
this->provides("debug")->addAttribute("joint_command",command_);
this->addProperty("kp",kp_);
this->addProperty("kd",kd_);
}
//! Called from gazebo
virtual bool gazeboConfigureHook(gazebo::physics::ModelPtr model)
{
if(model.get() == NULL) {return false;}
// Get the joints
gazebo_joints_ = model->GetJoints();
n_joints_ = gazebo_joints_.size();
// Get the joint names
for(std::vector<gazebo::physics::JointPtr>::iterator it=gazebo_joints_.begin();
it != gazebo_joints_.end();
++it)
{
joint_names_.push_back((**it).GetName());
}
state_posvel_.q.resize(n_joints_);
state_posvel_.qdot.resize(n_joints_);
state_effort_.resize(n_joints_);
command_.resize(n_joints_);
state_pos_.resize(n_joints_);
return true;
}
//! Called from Gazebo
virtual void gazeboUpdateHook(gazebo::physics::ModelPtr model)
{
if(model.get() == NULL) {return;}
// Synchronize with update()
RTT::os::MutexTryLock trylock(gazebo_mutex_);
if(trylock.isSuccessful()) {
// Increment simulation step counter (debugging)
steps_gz_++;
// Get the RTT and gazebo time for debugging purposes
rtt_time_ = 1E-9*RTT::os::TimeService::ticks2nsecs(RTT::os::TimeService::Instance()->getTicks());
gazebo::common::Time gz_time = model->GetWorld()->GetSimTime();
gz_time_ = (double)gz_time.sec + ((double)gz_time.nsec)*1E-9;
// Get the wall time
gazebo::common::Time gz_wall_time = gazebo::common::Time::GetWallTime();
wall_time_ = (double)gz_wall_time.sec + ((double)gz_wall_time.nsec)*1E-9;
// Get state
for(unsigned j=0; j < gazebo_joints_.size(); j++) {
state_pos_[j] = gazebo_joints_[j]->GetAngle(0).Radian();
state_posvel_.q(j) = state_pos_[j];
state_posvel_.qdot(j) = gazebo_joints_[j]->GetVelocity(0);
state_effort_(j) = gazebo_joints_[j]->GetForce(0u);
}
// Write command
switch(command_type_) {
case EFFORT:
for(unsigned int j=0; j < gazebo_joints_.size() && j < command_.size(); j++)
gazebo_joints_[j]->SetForce(0,command_[j]);
break;
case VELOCITY:
for(unsigned int j=0; j < gazebo_joints_.size() && j < command_.size(); j++)
gazebo_joints_[j]->SetVelocity(0,command_[j]);
break;
case POSITION:
for(unsigned int j=0; j < gazebo_joints_.size() && j < command_.size(); j++)
gazebo_joints_[j]->SetAngle(0,command_[j]);
break;
};
}
}
virtual bool configureHook()
{
return true;
}
virtual void updateHook()
{
// Synchronize with gazeboUpdate()
RTT::os::MutexLock lock(gazebo_mutex_);
// Compute period in simulation clock
static double last_update_time_sim;
period_sim_ = rtt_time_ - last_update_time_sim;
last_update_time_sim = rtt_time_;
// Compute period in wall clock
static double last_update_time_wall;
period_wall_ = wall_time_ - last_update_time_wall;
last_update_time_wall = wall_time_;
// Increment simulation step counter (debugging)
steps_rtt_++;
// Get command from ports
KDL::JntArray cmd;
if(port_cmd_effort.readNewest(cmd) == RTT::NewData) {
command_type_ = EFFORT;
} else if(port_cmd_velocity.readNewest(cmd) == RTT::NewData) {
command_type_ = VELOCITY;
} else if(port_cmd_position.readNewest(cmd) == RTT::NewData) {
command_type_ = POSITION;
}
// Set the command from the input port or from simple PD control
if(cmd.rows() > 0) {
for(unsigned int j=0; j < gazebo_joints_.size() && j < cmd.rows(); j++) {
command_[j] = cmd(j);
}
} else {
command_type_ = EFFORT;
for(unsigned int j=0; j < gazebo_joints_.size(); j++) {
command_[j] = -kp_*state_pos_[j] - kd_*state_pos_[j];
}
}
// Write state to ports
port_state_posvel.write(state_posvel_);
port_state_effort.write(state_effort_);
}
protected:
//! Synchronization
RTT::os::MutexRecursive gazebo_mutex_;
//! The Gazebo Model
//! The gazebo
std::vector<gazebo::physics::JointPtr> gazebo_joints_;
std::vector<std::string> joint_names_;
KDL::JntArrayVel state_posvel_;
KDL::JntArray state_effort_;
std::vector<double> state_pos_;
std::vector<double> command_;
RTT::OutputPort<std::vector<std::string> > port_state_names;
RTT::OutputPort<KDL::JntArrayVel> port_state_posvel;
RTT::OutputPort<KDL::JntArray> port_state_effort;
RTT::InputPort<KDL::JntArray> port_cmd_position;
RTT::InputPort<KDL::JntArray> port_cmd_velocity;
RTT::InputPort<KDL::JntArray> port_cmd_effort;
//! RTT time for debugging
double rtt_time_;
//! Gazebo time for debugging
double gz_time_;
double wall_time_;
//! Control gains
double kp_,kd_;
int steps_gz_;
int steps_rtt_;
int n_joints_;
double period_sim_;
double period_wall_;
CommandType command_type_;
};
ORO_LIST_COMPONENT_TYPE(DefaultGazeboComponent)
ORO_CREATE_COMPONENT_LIBRARY();