JaiaBot  1.20.0
JaiaBot micro-AUV software
liaison_jaiabot.h
Go to the documentation of this file.
1 #ifndef LIAISON_JAIABOT_H
2 #define LIAISON_JAIABOT_H
3 
4 #include <Wt/WEvent>
5 #include <Wt/WPushButton>
6 #include <Wt/WSlider>
7 #include <boost/thread/mutex.hpp>
8 #include <boost/units/io.hpp>
9 #include <chrono>
10 
11 #include "goby/zeromq/liaison/liaison_container.h"
12 #include <goby/middleware/frontseat/groups.h>
13 #include <goby/middleware/gpsd/groups.h>
14 #include <goby/middleware/protobuf/frontseat_data.pb.h>
15 #include <goby/middleware/protobuf/gpsd.pb.h>
16 
17 #include "jaiabot/groups.h"
20 #include "jaiabot/messages/sensor/salinity.pb.h"
21 
22 #include "config.pb.h"
23 #include "jaiabot/messages/feather.pb.h"
24 #include "jaiabot/messages/sensor/pressure_temperature.pb.h"
25 
26 namespace jaiabot
27 {
28 class CommsThread;
29 
30 class LiaisonJaiabot : public goby::zeromq::LiaisonContainerWithComms<LiaisonJaiabot, CommsThread>
31 {
32  public:
33  LiaisonJaiabot(const goby::apps::zeromq::protobuf::LiaisonConfig& cfg,
34  Wt::WContainerWidget* parent = 0);
35 
36  void post_control_ack(const protobuf::LowControlAck& ack);
37  void post_node_status(const goby::middleware::frontseat::protobuf::NodeStatus& node_status);
38  void post_tpv(const goby::middleware::protobuf::gpsd::TimePositionVelocity& tpv);
39  void post_pt(const jaiabot::protobuf::PressureTemperatureData& pt);
40  void post_salinity(const jaiabot::protobuf::SalinityData& salinity);
41  void post_imu(const jaiabot::protobuf::IMUData& imu);
42  void post_low_control(const jaiabot::protobuf::LowControl& low_control);
43 
44  private:
45  void loop();
46  void focus() override { timer_.start(); }
47  void unfocus() override { timer_.stop(); }
48 
49  void vehicle_select(Wt::WString msg);
50  void check_add_vehicle(int node_id);
51  void key_press(Wt::WKeyEvent key);
52  void key_release(Wt::WKeyEvent key);
53 
54  private:
55  Wt::WComboBox* vehicle_combo_;
56  Wt::WStackedWidget* vehicle_stack_;
57 
58  struct VehicleData
59  {
60  VehicleData(Wt::WStackedWidget*, const protobuf::JaiabotConfig&);
61 
62  Wt::WContainerWidget* vehicle_div;
63 
64  struct Controls
65  {
66  Controls(Wt::WContainerWidget* vehicle_div, const protobuf::JaiabotConfig& cfg);
67 
68  Wt::WGroupBox* controls_box;
69  Wt::WGroupBox* timeout_box;
70  Wt::WSlider* timeout_slider;
71  Wt::WContainerWidget* timeout_text_box;
72  Wt::WText* timeout_text{0};
73  Wt::WGroupBox* dive_box;
74  Wt::WContainerWidget* dive_button_box;
75  Wt::WPushButton* dive_button{0};
76  Wt::WContainerWidget* dive_slider_box;
77  Wt::WSlider* dive_slider;
78  Wt::WContainerWidget* dive_text_box;
79  Wt::WText* dive_text{0};
80  Wt::WGroupBox* motor_box;
81  Wt::WText* motor_left_text{0};
82  Wt::WSlider* motor_slider;
83  Wt::WText* motor_right_text{0};
84  Wt::WContainerWidget* motor_text_box;
85  Wt::WText* motor_text{0};
86  Wt::WGroupBox* fins_box;
87  Wt::WSlider* port_elevator_slider;
88  Wt::WText* rudder_left_text{0};
89  Wt::WSlider* rudder_slider;
90  Wt::WText* rudder_right_text{0};
91  Wt::WSlider* stbd_elevator_slider;
92  Wt::WContainerWidget* fins_text_box;
93  Wt::WText* fins_text{0};
94  Wt::WGroupBox* ack_box;
95  Wt::WText* ack_text{0};
96  Wt::WGroupBox* data_box;
97  Wt::WText* data_text{0};
98 
99  protobuf::LowControlAck latest_ack;
100 
101  // must be static, not sure why (segfault in JSignal otherwise)
102  static void timeout_slider_moved(int value, Wt::WText* text)
103  {
104  text->setText(timeout_text_from_value(value));
105  }
106 
107  static void dive_slider_moved(int value, Wt::WText* text)
108  {
109  text->setText(dive_text_from_value(value));
110  }
111 
112  static void dive_button_clicked(Wt::WMouseEvent) { dive_start_ = true; }
113 
114  static void motor_slider_moved(int value, Wt::WText* text)
115  {
116  text->setText(motor_text_from_value(value));
117  }
118 
119  static void port_elevator_slider_moved(int value, Wt::WText* text,
120  Wt::WSlider* stbd_elevator, Wt::WSlider* rudder)
121  {
122  text->setText(fins_text_from_value(value, stbd_elevator->value(), rudder->value()));
123  }
124 
125  static void stbd_elevator_slider_moved(int value, Wt::WText* text,
126  Wt::WSlider* port_elevator, Wt::WSlider* rudder)
127  {
128  text->setText(fins_text_from_value(port_elevator->value(), value, rudder->value()));
129  }
130  static void rudder_slider_moved(int value, Wt::WText* text, Wt::WSlider* port_elevator,
131  Wt::WSlider* stbd_elevator)
132  {
133  text->setText(
134  fins_text_from_value(port_elevator->value(), stbd_elevator->value(), value));
135  }
136 
137  void set_port_elevator_value(int value)
138  {
139  port_elevator_slider->setValue(value);
140  fins_text->setText(fins_text_from_value(port_elevator_slider->value(),
141  stbd_elevator_slider->value(),
142  rudder_slider->value()));
143  }
144 
145  void set_stbd_elevator_value(int value)
146  {
147  stbd_elevator_slider->setValue(value);
148  fins_text->setText(fins_text_from_value(port_elevator_slider->value(),
149  stbd_elevator_slider->value(),
150  rudder_slider->value()));
151  }
152 
153  void set_rudder_value(int value)
154  {
155  rudder_slider->setValue(value);
156  fins_text->setText(fins_text_from_value(port_elevator_slider->value(),
157  stbd_elevator_slider->value(),
158  rudder_slider->value()));
159  }
160 
161  void set_motor_value(int value)
162  {
163  motor_slider->setValue(value);
164  motor_text->setText(motor_text_from_value(motor_slider->value()));
165  }
166 
167  void set_timeout_value(int value)
168  {
169  timeout_slider->setValue(value);
170  timeout_text->setText(timeout_text_from_value(timeout_slider->value()));
171  }
172 
173  void set_dive_value(int value)
174  {
175  dive_slider->setValue(value);
176  dive_text->setText(dive_text_from_value(dive_slider->value()));
177  }
178  };
179 
180  Controls low_level_control;
181 
182  int index_in_stack{0};
183 
184  static std::string timeout_text_from_value(int value)
185  {
186  return "Timeout (X-/V+): " + std::to_string(value);
187  }
188 
189  static std::string dive_text_from_value(int value)
190  {
191  return "Dive (Y-/U+): " + std::to_string(value);
192  }
193 
194  static std::string motor_text_from_value(int value)
195  {
196  return "Motor (W-/R+): " + std::to_string(value);
197  }
198  static std::string fins_text_from_value(int port_elevator_value, int stbd_elevator_value,
199  int rudder_value)
200  {
201  return "Port Elevator (A-/Q+ or D-/E+ for both): " +
202  std::to_string(port_elevator_value) +
203  "<br/>Starboard Elevator (G-/T+ or D-/E+ for both): " +
204  std::to_string(stbd_elevator_value) +
205  "<br/>Rudder (S-/F+): " + std::to_string(rudder_value);
206  }
207  };
208 
209  // vehicle id to Data
210  std::map<int, VehicleData> vehicle_data_;
211 
212  // convenient info shown on vehicle's liaison
213  Wt::WGroupBox* bot_node_status_box_;
214  Wt::WText* bot_node_status_text_;
215  Wt::WGroupBox* bot_tpv_box_;
216  Wt::WText* bot_tpv_text_;
217  Wt::WGroupBox* bot_pt_box_;
218  Wt::WText* bot_pt_text_;
219  Wt::WGroupBox* bot_salinity_box_;
220  Wt::WText* bot_salinity_text_;
221  Wt::WGroupBox* bot_imu_box_;
222  Wt::WText* bot_imu_text_;
223  Wt::WGroupBox* bot_low_control_box_;
224  Wt::WText* bot_low_control_text_;
225 
226  // currently shown vehicle id
227  int current_vehicle_{-1};
228 
229  bool motor_go_{false};
230  static bool dive_start_;
231  static std::chrono::system_clock::time_point dive_expire_;
232 
233  Wt::WTimer timer_;
234  friend class CommsThread;
235  const protobuf::JaiabotConfig& cfg_;
236 };
237 
238 class CommsThread : public goby::zeromq::LiaisonCommsThread<LiaisonJaiabot>
239 {
240  public:
241  CommsThread(LiaisonJaiabot* tab, const goby::apps::zeromq::protobuf::LiaisonConfig& config,
242  int index)
243  : LiaisonCommsThread<LiaisonJaiabot>(tab, config, index), tab_(tab)
244  {
245  interprocess().subscribe<groups::control_ack>([this](const protobuf::LowControlAck& ack) {
246  tab_->post_to_wt([=]() { tab_->post_control_ack(ack); });
247  });
248 
249  // post the NodeStatus message in its own box
250  interprocess().subscribe<goby::middleware::frontseat::groups::node_status>(
251  [this](const goby::middleware::frontseat::protobuf::NodeStatus& node_status) {
252  tab_->post_to_wt([=]() { tab_->post_node_status(node_status); });
253  });
254 
255  // post the tpv in its own box
256  interprocess().subscribe<goby::middleware::groups::gpsd::tpv>(
257  [this](const goby::middleware::protobuf::gpsd::TimePositionVelocity& tpv) {
258  tab_->post_to_wt([=]() { tab_->post_tpv(tpv); });
259  });
260 
261  // post the pt data in its own box
262  interprocess().subscribe<groups::pressure_temperature>(
263  [this](const jaiabot::protobuf::PressureTemperatureData& pt) {
264  tab_->post_to_wt([=]() { tab_->post_pt(pt); });
265  });
266 
267  // post the salinity data in its own box
268  interprocess().subscribe<groups::salinity>(
269  [this](const jaiabot::protobuf::SalinityData& salinity) {
270  tab_->post_to_wt([=]() { tab_->post_salinity(salinity); });
271  });
272 
273  // post the imu data in its own box
274  interprocess().subscribe<groups::imu>([this](const jaiabot::protobuf::IMUData& imu) {
275  tab_->post_to_wt([=]() { tab_->post_imu(imu); });
276  });
277 
278  // post the control surfaces data in its own box
279  interprocess().subscribe<groups::low_control>(
280  [this](const jaiabot::protobuf::LowControl& low_control) {
281  tab_->post_to_wt([=]() { tab_->post_low_control(low_control); });
282  });
283 
284  } // namespace jaiabot
286 
287  private:
288  friend class LiaisonJaiabot;
289  LiaisonJaiabot* tab_;
290 };
291 
292 } // namespace jaiabot
293 
294 #endif
CommsThread(LiaisonJaiabot *tab, const goby::apps::zeromq::protobuf::LiaisonConfig &config, int index)
void post_imu(const jaiabot::protobuf::IMUData &imu)
void post_control_ack(const protobuf::LowControlAck &ack)
void post_tpv(const goby::middleware::protobuf::gpsd::TimePositionVelocity &tpv)
void post_low_control(const jaiabot::protobuf::LowControl &low_control)
LiaisonJaiabot(const goby::apps::zeromq::protobuf::LiaisonConfig &cfg, Wt::WContainerWidget *parent=0)
void post_pt(const jaiabot::protobuf::PressureTemperatureData &pt)
void post_node_status(const goby::middleware::frontseat::protobuf::NodeStatus &node_status)
void post_salinity(const jaiabot::protobuf::SalinityData &salinity)
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::jaia::MessageOptions >, 11, false > msg
constexpr goby::middleware::Group imu
Definition: groups.h:42
constexpr goby::middleware::Group pressure_temperature
Definition: groups.h:43
constexpr goby::middleware::Group low_control
Definition: groups.h:61
constexpr goby::middleware::Group salinity
Definition: groups.h:45
constexpr goby::middleware::Group control_ack
Definition: groups.h:62
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::goby::acomms::protobuf::DriverConfig, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::jaiabot::udp::protobuf::Config >, 11, false > config
static void dive_slider_moved(int value, Wt::WText *text)
static void timeout_slider_moved(int value, Wt::WText *text)
static void dive_button_clicked(Wt::WMouseEvent)
static void rudder_slider_moved(int value, Wt::WText *text, Wt::WSlider *port_elevator, Wt::WSlider *stbd_elevator)
Controls(Wt::WContainerWidget *vehicle_div, const protobuf::JaiabotConfig &cfg)
static void stbd_elevator_slider_moved(int value, Wt::WText *text, Wt::WSlider *port_elevator, Wt::WSlider *rudder)
static void port_elevator_slider_moved(int value, Wt::WText *text, Wt::WSlider *stbd_elevator, Wt::WSlider *rudder)
static void motor_slider_moved(int value, Wt::WText *text)