MAV'RIC
|
00001 /******************************************************************************* 00002 * Copyright (c) 2009-2016, MAV'RIC Development Team 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of the copyright holder nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software without 00017 * specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 ******************************************************************************/ 00031 00032 /******************************************************************************* 00033 * \file servos_mix_matrix.hpp 00034 * 00035 * \author MAV'RIC Team 00036 * 00037 * \brief Servo mix 00038 * 00039 * Example use for hexhog, an hexacopter with tilted motors: 00040 * 00041 * ```cpp 00042 * # Some required variables 00043 * torque_command_t torque_command; 00044 * thrust_command_t thrust_command; 00045 * thrust3D_command_t thrust3d_command; 00046 * 00047 * // Configuration structure 00048 * Servos_mix_matrix<6>::conf_t servosmix_config = Servos_mix_matrix<6>::default_config(); 00049 * float s60 = 0.866025f; 00050 * servosmix_config.mix = Mat<6, 6>({ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 00051 * s60, 0.5f, -1.0f, -0.5f, s60, 1.0f, 00052 * s60, -0.5f, 1.0f, -0.5f, -s60, 1.0f, 00053 * 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 00054 * -s60, -0.5f, 1.0f, -0.5f, s60, 1.0f, 00055 * -s60, 0.5f, -1.0f, -0.5f, -s60, 1.0f}); 00056 * 00057 * # Create object 00058 * Servos_mix_matrix<6> servosmix( torque_command, 00059 * thrust3d_command, 00060 * std::array<Servo*, 6>{&board.servo_0, &board.servo_1, 00061 * &board.servo_4, &board.servo_5}, 00062 * servosmix_config); 00063 * ``` 00064 ******************************************************************************/ 00065 00066 00067 #ifndef SERVOS_MIX_MATRIX_HPP_ 00068 #define SERVOS_MIX_MATRIX_HPP_ 00069 00070 #include "control/servos_mix.hpp" 00071 #include "drivers/servo.hpp" 00072 #include "util/matrix.hpp" 00073 00079 template<uint32_t N> 00080 class Servos_mix_matrix: public Servos_mix 00081 { 00082 public: 00086 struct conf_t 00087 { 00088 Mat<N, 6> mix; 00089 Mat<N, 1> trim; 00090 Mat<N, 1> min; 00091 Mat<N, 1> max; 00092 }; 00093 00099 static inline conf_t default_config(void) 00100 { 00101 conf_t conf = {}; 00102 conf.mix = Mat<N,6>(0.0f); 00103 conf.trim = Mat<N,1>(-1.0f); // -1.0f in case some servos are motors 00104 conf.min = Mat<N,1>(-0.9f); 00105 conf.max = Mat<N,1>(1.0f); 00106 return conf; 00107 }; 00108 00109 00113 struct args_t 00114 { 00115 std::array<Servo*, N> servos; 00116 }; 00117 00121 Servos_mix_matrix( const args_t& args, 00122 const conf_t& config = default_config()): 00123 servos_(args.servos), 00124 torque_command_(torque_command_t{{{0.0f, 0.0f, 0.0f}}}), 00125 thrust_command_(thrust_command_t{{{0.0f, 0.0f, 0.0f}}}), 00126 mix_(config.mix), 00127 trim_(config.trim), 00128 min_(config.min), 00129 max_(config.max) 00130 {}; 00131 00132 00136 virtual bool update(void) 00137 { 00138 // Mix commands into servo values 00139 Mat<N,1> servos_cmd = mix_ % Mat<6,1>({torque_command_.xyz[X], 00140 torque_command_.xyz[Y], 00141 torque_command_.xyz[Z], 00142 thrust_command_.xyz[X], 00143 thrust_command_.xyz[Y], 00144 thrust_command_.xyz[Z]}); 00145 00146 // Add trim 00147 servos_cmd += trim_; 00148 00149 // Clip between min and max actuator values 00150 servos_cmd.clip(min_, max_); 00151 00152 // Write to hardware 00153 for (uint32_t i=0; i<N; ++i) 00154 { 00155 servos_[i]->write(servos_cmd[i]); 00156 } 00157 00158 return true; 00159 }; 00160 00161 00162 virtual bool failsafe(void) 00163 { 00164 for (uint32_t i = 0; i < N; i++) 00165 { 00166 servos_[i]->failsafe(); 00167 } 00168 00169 return true; 00170 } 00171 00172 00180 virtual bool set_command(const torque_command_t& torque) 00181 { 00182 torque_command_ = torque; 00183 return true; 00184 }; 00185 00186 00194 virtual bool set_command(const thrust_command_t& thrust) 00195 { 00196 thrust_command_ = thrust; 00197 return true; 00198 }; 00199 00200 00208 virtual bool get_command(torque_command_t& torque) const 00209 { 00210 torque = torque_command_; 00211 return true; 00212 } 00213 00214 00222 virtual bool get_command(thrust_command_t& thrust) const 00223 { 00224 thrust = thrust_command_; 00225 return true; 00226 }; 00227 00228 00229 protected: 00230 std::array<Servo*, N> servos_; 00231 00232 torque_command_t torque_command_; 00233 thrust_command_t thrust_command_; 00234 00235 Mat<N, 6> mix_; 00236 Mat<N, 1> trim_; 00237 Mat<N, 1> min_; 00238 Mat<N, 1> max_; 00239 }; 00240 00241 00242 #endif /* SERVOS_MIX_MATRIX_HPP_ */