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