inno_vtol_reverse_mixer_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022-2023 RaccoonLab.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, version 3.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
17  */
18 
19 #include <ros/ros.h>
20 #include <sensor_msgs/Joy.h>
21 
22 static constexpr char MAPPED_ACTUATOR_TOPIC[] = "/uav/actuators";
23 static constexpr char RAW_ACTUATOR_TOPIC[] = "/uav/actuators_raw";
24 
34 };
35 
45 };
46 
56 };
57 
59  public:
60  explicit BaseReverseMixer(const ros::NodeHandle& nh): _node(nh) {}
61  virtual ~BaseReverseMixer() = default;
62  int8_t init();
63  virtual void rawActuatorsCallback(sensor_msgs::Joy msg) = 0;
64 
66  sensor_msgs::Joy mappedActuatorMsg_;
67  private:
70 };
71 
75  return 0;
76 }
77 
78 
80  public:
82  for (size_t channel = 0; channel < 8; channel++) {
83  mappedActuatorMsg_.axes.push_back(0);
84  }
85  }
86  ~BabysharkReverseMixer() final = default;
87  protected:
88  void rawActuatorsCallback(sensor_msgs::Joy msg) override;
89 };
90 void BabysharkReverseMixer::rawActuatorsCallback(sensor_msgs::Joy msg) {
91  if (msg.axes.size() == 8) {
92  mappedActuatorMsg_.header = msg.header;
93 
98 
99  float roll = msg.axes[BABY_SHARK_AILERONS];
100  roll = (roll < 0) ? 0.5 : 1 - roll;
101  mappedActuatorMsg_.axes[VTOL_ROLL] = roll;
102 
103  float pitch = -msg.axes[BABY_SHARK_A_TAIL_LEFT] + msg.axes[BABY_SHARK_A_TAIL_RIGHT];
104  pitch = (pitch < 0) ? 0.0f : pitch / 0.8f;
105  mappedActuatorMsg_.axes[VTOL_PITCH] = pitch;
106 
107  float yaw = msg.axes[BABY_SHARK_A_TAIL_LEFT] + msg.axes[BABY_SHARK_A_TAIL_RIGHT];
108  yaw = (yaw < 0) ? 0.0f : (1.0f - yaw) / 0.7f;
109  mappedActuatorMsg_.axes[VTOL_YAW] = yaw;
110 
113  }
114 }
115 
116 
118  public:
120  ~InnoVtolReverseMixer() final = default;
121  protected:
122  void rawActuatorsCallback(sensor_msgs::Joy msg) override;
123 };
124 void InnoVtolReverseMixer::rawActuatorsCallback(sensor_msgs::Joy msg) {
125  if (msg.axes.size() == 8) {
126  if (msg.axes[4] < 0) {
127  msg.axes[4] = 0.5;
128  }
129  msg.axes[5] = (msg.axes[5] >= 0) ? msg.axes[5] * 2.0f - 1.0f : 0.0f;
130  msg.axes[6] = (msg.axes[6] >= 0) ? msg.axes[6] * 2.0f - 1.0f : 0.0f;
131  msg.axes[7] = msg.axes[7] / 0.75f;
133  } else if (msg.axes.size() == 4) {
134  msg.axes.push_back(0.5);
135  msg.axes.push_back(0.0);
136  msg.axes.push_back(0.0);
137  msg.axes.push_back(0.0);
139  }
140 }
141 
143  public:
145  for (size_t channel = 0; channel < 4; channel++) {
146  mappedActuatorMsg_.axes.push_back(0);
147  }
148  }
149  ~IrisReverseMixer() final = default;
150  protected:
151  void rawActuatorsCallback(sensor_msgs::Joy msg) override;
152 };
153 void IrisReverseMixer::rawActuatorsCallback(sensor_msgs::Joy msg) {
154  if (msg.axes.size() >= 4) {
155  mappedActuatorMsg_.axes[0] = msg.axes[0];
156  mappedActuatorMsg_.axes[1] = msg.axes[1];
157  mappedActuatorMsg_.axes[2] = msg.axes[2];
158  mappedActuatorMsg_.axes[3] = msg.axes[3];
159 
160  mappedActuatorMsg_.header = msg.header;
162  }
163 }
164 
165 
166 int main(int argc, char **argv){
167  ros::init(argc, argv, "inno_vtol_reverse_mixer_node");
170  }
171 
172  ros::NodeHandle node_handler("inno_vtol_reverse_mixer");
173  std::string airframe;
174  if(!node_handler.getParam("airframe", airframe)){
175  ROS_ERROR("ReverseMixer: There is no `airframe` parameter.");
176  return -1;
177  }
178 
179  std::unique_ptr<BaseReverseMixer> reverseMixer;
180  if (airframe == "babyshark_standard_vtol") {
181  reverseMixer = std::make_unique<BabysharkReverseMixer>(node_handler);
182  } else if (airframe == "inno_standard_vtol") {
183  reverseMixer = std::make_unique<InnoVtolReverseMixer>(node_handler);
184  } else if (airframe == "iris") {
185  reverseMixer = std::make_unique<IrisReverseMixer>(node_handler);
186  } else {
187  ROS_ERROR("ReverseMixer: Wrong `/uav/sim_params/airframe` parameter.");
188  return -1;
189  }
190  ROS_INFO_STREAM("ReverseMixer: airframe is " << airframe.c_str());
191 
192  if (reverseMixer->init() == -1){
193  ROS_ERROR("Shutdown.");
194  ros::shutdown();
195  return 0;
196  }
197 
198  ros::spin();
199  return 0;
200 }
static constexpr char MAPPED_ACTUATOR_TOPIC[]
BabysharkReverseMixer(const ros::NodeHandle &nh)
virtual ~BaseReverseMixer()=default
int main(int argc, char **argv)
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
void rawActuatorsCallback(sensor_msgs::Joy msg) override
f
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void rawActuatorsCallback(sensor_msgs::Joy msg) override
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual void rawActuatorsCallback(sensor_msgs::Joy msg)=0
void publish(const boost::shared_ptr< M > &message) const
void rawActuatorsCallback(sensor_msgs::Joy msg) override
bool getParam(const std::string &key, std::string &s) const
BaseReverseMixer(const ros::NodeHandle &nh)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
IrisReverseMixer(const ros::NodeHandle &nh)
#define ROS_INFO_STREAM(args)
ROSCPP_DECL void shutdown()
static constexpr char RAW_ACTUATOR_TOPIC[]
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
#define ROS_ERROR(...)
#define ROSCONSOLE_DEFAULT_NAME


inno_vtol_dynamics
Author(s): Roman Fedorenko, Dmitry Ponomarev, Ezra Tal, Winter Guerra
autogenerated on Sat Jul 1 2023 02:13:44