quadrotor_interface.cpp
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2012-2016, Institute of Flight Systems and Automatic Control,
3 // Technische Universität Darmstadt.
4 // All rights reserved.
5 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of hector_quadrotor nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //=================================================================================================
28 
30 
31 #include <cmath>
32 
34 
36 {}
37 
39 {}
40 
41 bool QuadrotorInterface::enabled(const CommandHandle *handle) const
42 {
43  if (!handle || !handle->connected()) return false;
44  std::string resource = handle->getName();
45  return enabled_.count(resource) > 0;
46 }
47 
49 {
50  if (!handle || !handle->connected()) return false;
51  std::string resource = handle->getName();
52  std::map<std::string, const CommandHandle *>::iterator it = enabled_.find(resource);
53  if (it == enabled_.end()) {
54  enabled_[resource] = handle;
55  ROS_INFO_NAMED("quadrotor_interface", "Enabled %s output", resource.c_str());
56  return true;
57  } else if (it->second == handle) {
58  return true;
59  }
60  return false;
61 }
62 
64 {
65  if (!handle) return false;
66  std::string resource = handle->getName();
67  std::map<std::string, const CommandHandle *>::iterator it = enabled_.find(resource);
68  if (it != enabled_.end() && it->second == handle) {
69  enabled_.erase(it);
70  ROS_INFO_NAMED("quadrotor_interface", "Disabled %s control", resource.c_str());
71  return true;
72  }
73  return false;
74 }
75 
77 {
78  if (!handle) return;
79  std::string resource = handle->getName();
80  if (inputs_.count(resource)) {
81  const CommandHandlePtr& input = inputs_.at(resource);
82  if (input.get() != handle) input->reset();
83  }
84  if (outputs_.count(resource)) {
85  const CommandHandlePtr& output = outputs_.at(resource);
86  if (output.get() != handle) output->reset();
87  }
88 }
89 
91  std::string resource = handle->getName();
92  if (outputs_.count(resource))
93  {
94  CommandHandlePtr output = outputs_.at(resource);
95  if (output) {
96  output->setPreempted();
97  return true;
98  }
99  }
100  return false;
101 }
102 
103 const Pose *QuadrotorInterface::getPoseCommand() const { return getCommand<PoseCommandHandle>("pose"); }
104 const Twist *QuadrotorInterface::getTwistCommand() const { return getCommand<TwistCommandHandle>("twist"); }
105 const Wrench *QuadrotorInterface::getWrenchCommand() const { return getCommand<WrenchCommandHandle>("wrench"); }
106 const MotorCommand *QuadrotorInterface::getMotorCommand() const { return getCommand<MotorCommandHandle>("motor"); }
107 
108 void PoseHandle::getEulerRPY(double &roll, double &pitch, double &yaw) const
109 {
110  const Quaternion::_w_type& w = pose().orientation.w;
111  const Quaternion::_x_type& x = pose().orientation.x;
112  const Quaternion::_y_type& y = pose().orientation.y;
113  const Quaternion::_z_type& z = pose().orientation.z;
114  roll = atan2(2.*y*z + 2.*w*x, z*z - y*y - x*x + w*w);
115  pitch = -asin(2.*x*z - 2.*w*y);
116  yaw = atan2(2.*x*y + 2.*w*z, x*x + w*w - z*z - y*y);
117 }
118 
119 double PoseHandle::getYaw() const
120 {
121  const Quaternion::_w_type& w = pose().orientation.w;
122  const Quaternion::_x_type& x = pose().orientation.x;
123  const Quaternion::_y_type& y = pose().orientation.y;
124  const Quaternion::_z_type& z = pose().orientation.z;
125  return atan2(2.*x*y + 2.*w*z, x*x + w*w - z*z - y*y);
126 }
127 
128 Vector3 PoseHandle::toBody(const Vector3& nav) const
129 {
130  const Quaternion::_w_type& w = pose().orientation.w;
131  const Quaternion::_x_type& x = pose().orientation.x;
132  const Quaternion::_y_type& y = pose().orientation.y;
133  const Quaternion::_z_type& z = pose().orientation.z;
134  Vector3 body;
135  body.x = (w*w+x*x-y*y-z*z) * nav.x + (2.*x*y + 2.*w*z) * nav.y + (2.*x*z - 2.*w*y) * nav.z;
136  body.y = (2.*x*y - 2.*w*z) * nav.x + (w*w-x*x+y*y-z*z) * nav.y + (2.*y*z + 2.*w*x) * nav.z;
137  body.z = (2.*x*z + 2.*w*y) * nav.x + (2.*y*z - 2.*w*x) * nav.y + (w*w-x*x-y*y+z*z) * nav.z;
138  return body;
139 }
140 
141 Vector3 PoseHandle::fromBody(const Vector3& body) const
142 {
143  const Quaternion::_w_type& w = pose().orientation.w;
144  const Quaternion::_x_type& x = pose().orientation.x;
145  const Quaternion::_y_type& y = pose().orientation.y;
146  const Quaternion::_z_type& z = pose().orientation.z;
147  Vector3 nav;
148  nav.x = (w*w+x*x-y*y-z*z) * body.x + (2.*x*y - 2.*w*z) * body.y + (2.*x*z + 2.*w*y) * body.z;
149  nav.y = (2.*x*y + 2.*w*z) * body.x + (w*w-x*x+y*y-z*z) * body.y + (2.*y*z - 2.*w*x) * body.z;
150  nav.z = (2.*x*z - 2.*w*y) * body.x + (2.*y*z + 2.*w*x) * body.y + (w*w-x*x-y*y+z*z) * body.z;
151  return nav;
152 }
153 
154 void HorizontalPositionCommandHandle::getError(const PoseHandle &pose, double &x, double &y) const
155 {
156  getCommand(x, y);
157  x -= pose.get()->position.x;
158  y -= pose.get()->position.y;
159 }
160 
161 double HeightCommandHandle::getError(const PoseHandle &pose) const
162 {
163  return getCommand() - pose.get()->position.z;
164 }
165 
167 {
168  if (get()) {
169  get()->x = 0.0;
170  get()->y = 0.0;
171  get()->z = sin(command / 2.);
172  get()->w = cos(command / 2.);
173  }
174 
175  if (scalar_) {
176  *scalar_ = command;
177  }
178 }
179 
181  if (scalar_) return *scalar_;
182  const Quaternion::_w_type& w = get()->w;
183  const Quaternion::_x_type& x = get()->x;
184  const Quaternion::_y_type& y = get()->y;
185  const Quaternion::_z_type& z = get()->z;
186  return atan2(2.*x*y + 2.*w*z, x*x + w*w - z*z - y*y);
187 }
188 
189 bool HeadingCommandHandle::update(Pose& command) const {
190  if (get()) {
191  command.orientation = *get();
192  return true;
193  }
194  if (scalar_) {
195  command.orientation.x = 0.0;
196  command.orientation.y = 0.0;
197  command.orientation.z = sin(*scalar_ / 2.);
198  command.orientation.x = cos(*scalar_ / 2.);
199  return true;
200  }
201  return false;
202 }
203 
204 double HeadingCommandHandle::getError(const PoseHandle &pose) const {
205  static const double M_2PI = 2.0 * M_PI;
206  double error = getCommand() - pose.getYaw() + M_PI;
207  error -= floor(error / M_2PI) * M_2PI;
208  return error - M_PI;
209 }
210 
211 bool CommandHandle::enabled() { return interface_->enabled(this); }
212 bool CommandHandle::start() { preempted_ = false; return interface_->start(this); }
213 void CommandHandle::stop() { preempted_ = false; interface_->stop(this); }
214 void CommandHandle::disconnect() { interface_->disconnect(this); }
215 
216 bool CommandHandle::preempt() { return interface_->preempt(this); }
217 void CommandHandle::setPreempted() { preempted_ = true; }
218 bool CommandHandle::preempted() { return preempted_; }
219 
220 } // namespace hector_quadrotor_interface
#define ROS_INFO_NAMED(name,...)
Vector3 toBody(const Vector3 &nav) const
void getError(const PoseHandle &pose, double &x, double &y) const
void disconnect(const CommandHandle *handle)
Vector3 fromBody(const Vector3 &nav) const
virtual const std::string & getName() const
Definition: handles.h:181
std::map< std::string, CommandHandlePtr > outputs_
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
HandleType::ValueType const * getCommand(const std::string &name) const
bool enabled(const CommandHandle *handle) const
double getError(const PoseHandle &pose) const
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
std::map< std::string, const CommandHandle * > enabled_
double getError(const PoseHandle &pose) const
const ValueType * get() const
Definition: handles.h:80
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
void getEulerRPY(double &roll, double &pitch, double &yaw) const
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
std::map< std::string, CommandHandlePtr > inputs_


hector_quadrotor_interface
Author(s): Johannes Meyer , Paul Bovbel
autogenerated on Mon Jun 10 2019 13:36:46