23 #include "goby/common/logger.h" 24 #include "goby/util/sci.h" 26 #include "goby/util/seawater/depth.h" 27 #include "goby/util/seawater/salinity.h" 28 #include "goby/util/seawater/swstate.h" 30 #include "frontseat.h" 39 : cfg_(cfg), helm_state_(
gpb::HELM_NOT_RUNNING), state_(
gpb::INTERFACE_STANDBY),
41 last_frontseat_error_(
gpb::ERROR_FRONTSEAT_NONE), last_helm_error_(
gpb::ERROR_HELM_NONE)
45 signal_raw_from_frontseat.connect(
46 boost::bind(&FrontSeatInterfaceBase::glog_raw,
this, _1, DIRECTION_FROM_FRONTSEAT));
47 signal_raw_to_frontseat.connect(
48 boost::bind(&FrontSeatInterfaceBase::glog_raw,
this, _1, DIRECTION_TO_FRONTSEAT));
51 if (!geodesy_.Initialise(cfg_.common().lat_origin(), cfg_.common().lon_origin()))
53 glog.is(DIE) &&
glog <<
"Failed to initialize MOOS Geodesy. Check LatOrigin and LongOrigin." 57 glog_out_group_ =
"FrontSeatInterfaceBase::raw::out";
58 glog_in_group_ =
"FrontSeatInterfaceBase::raw::in";
64 void FrontSeatInterfaceBase::do_work()
73 if (e.is_helm_error())
75 last_helm_error_ = e.helm_err();
76 state_ = gpb::INTERFACE_HELM_ERROR;
77 signal_state_change(state_);
79 else if (e.is_fs_error())
81 last_frontseat_error_ = e.fs_err();
82 state_ = gpb::INTERFACE_FS_ERROR;
83 signal_state_change(state_);
89 void FrontSeatInterfaceBase::check_change_state()
92 gpb::InterfaceState previous_state = state_;
95 case gpb::INTERFACE_STANDBY:
96 if (frontseat_providing_data())
97 state_ = gpb::INTERFACE_LISTEN;
102 case gpb::INTERFACE_LISTEN:
103 if (frontseat_state() == gpb::FRONTSEAT_ACCEPTING_COMMANDS &&
104 (helm_state() == gpb::HELM_DRIVE || !cfg_.require_helm()))
105 state_ = gpb::INTERFACE_COMMAND;
107 check_error_states();
110 case gpb::INTERFACE_COMMAND:
111 if (frontseat_state() == gpb::FRONTSEAT_IN_CONTROL ||
112 frontseat_state() == gpb::FRONTSEAT_IDLE)
113 state_ = gpb::INTERFACE_LISTEN;
115 check_error_states();
118 case gpb::INTERFACE_HELM_ERROR:
120 if (helm_state() == gpb::HELM_DRIVE)
122 last_helm_error_ = gpb::ERROR_HELM_NONE;
123 state_ = gpb::INTERFACE_STANDBY;
127 case gpb::INTERFACE_FS_ERROR:
129 if (last_frontseat_error_ == gpb::ERROR_FRONTSEAT_NOT_CONNECTED &&
130 frontseat_state() != gpb::FRONTSEAT_NOT_CONNECTED)
132 last_frontseat_error_ = gpb::ERROR_FRONTSEAT_NONE;
133 state_ = gpb::INTERFACE_STANDBY;
135 else if (last_frontseat_error_ == gpb::ERROR_FRONTSEAT_NOT_PROVIDING_DATA &&
136 frontseat_providing_data())
138 last_frontseat_error_ = gpb::ERROR_FRONTSEAT_NONE;
139 state_ = gpb::INTERFACE_STANDBY;
144 if (state_ != previous_state)
145 signal_state_change(state_);
148 void FrontSeatInterfaceBase::check_error_states()
151 if (helm_state() == gpb::HELM_PARK)
155 else if (cfg_.require_helm() &&
156 (helm_state() == gpb::HELM_NOT_RUNNING &&
157 (state_ == gpb::INTERFACE_COMMAND ||
163 if (frontseat_state() == gpb::FRONTSEAT_NOT_CONNECTED &&
164 (state_ != gpb::INTERFACE_STANDBY ||
168 else if (!frontseat_providing_data() && state_ != gpb::INTERFACE_STANDBY)
172 void FrontSeatInterfaceBase::glog_raw(
const gpb::FrontSeatRaw& raw_msg, Direction direction)
174 if (direction == DIRECTION_TO_FRONTSEAT)
175 glog << group(glog_out_group_);
176 else if (direction == DIRECTION_FROM_FRONTSEAT)
177 glog << group(glog_in_group_);
179 switch (raw_msg.type())
181 case gpb::FrontSeatRaw::RAW_ASCII:
182 glog << raw_msg.raw() <<
"\n" 183 <<
"^ " <<
magenta << raw_msg.description() <<
nocolor << std::endl;
185 case gpb::FrontSeatRaw::RAW_BINARY:
186 glog << raw_msg.raw().size() <<
"byte message\n" 187 <<
"^ " <<
magenta << raw_msg.description() <<
nocolor << std::endl;
192 void FrontSeatInterfaceBase::compute_missing(
gpb::CTDSample* ctd_sample)
194 double pressure_dbar = ctd_sample->pressure() / 10000;
195 if (!ctd_sample->has_salinity())
197 double conductivity_mSiemens_cm = ctd_sample->conductivity() * 10;
198 double temperature_deg_C = ctd_sample->temperature();
199 ctd_sample->set_salinity(SalinityCalculator::salinity(conductivity_mSiemens_cm,
200 temperature_deg_C, pressure_dbar));
201 ctd_sample->set_salinity_algorithm(gpb::CTDSample::UNESCO_44_PREKIN_AND_LEWIS_1980);
203 if (!ctd_sample->has_depth())
205 ctd_sample->set_depth(pressure2depth(pressure_dbar, ctd_sample->lat()));
207 if (!ctd_sample->has_sound_speed())
209 ctd_sample->set_sound_speed(goby::util::mackenzie_soundspeed(
210 ctd_sample->temperature(), ctd_sample->salinity(), ctd_sample->depth()));
212 ctd_sample->set_sound_speed_algorithm(gpb::CTDSample::MACKENZIE_1981);
214 if (!ctd_sample->has_density())
216 ctd_sample->set_density(
217 density_anomaly(ctd_sample->salinity(), ctd_sample->temperature(), pressure_dbar) +
220 ctd_sample->set_density_algorithm(gpb::CTDSample::UNESCO_38_MILLERO_AND_POISSON_1981);
226 if (!status->has_name())
227 status->set_name(cfg_.common().community());
228 if (!status->has_modem_id())
229 status->set_modem_id(cfg_.modem_id());
231 if (!status->has_global_fix() && !status->has_local_fix())
234 glog <<
"Cannot 'compute_missing' on NodeStatus when global_fix and local_fix are both " 235 "missing (cannot make up a position from nothing)!" 239 else if (!status->has_global_fix())
242 if (status->local_fix().has_z())
243 status->mutable_global_fix()->set_depth(-status->local_fix().z());
246 geodesy_.UTM2LatLong(status->local_fix().x(), status->local_fix().y(), lat, lon);
247 status->mutable_global_fix()->set_lat(lat);
248 status->mutable_global_fix()->set_lon(lon);
250 else if (!status->has_local_fix())
253 if (status->global_fix().has_depth())
254 status->mutable_local_fix()->set_z(-status->global_fix().depth());
257 geodesy_.LatLong2LocalUTM(status->global_fix().lat(), status->global_fix().lon(), y, x);
258 status->mutable_local_fix()->set_x(x);
259 status->mutable_local_fix()->set_y(y);
Contains functions for adding color to Terminal window streams.
std::ostream & magenta(std::ostream &os)
All text following this manipulator is magenta (e.g. std::cout << magenta << "text";) ...
double goby_time< double >()
Returns current UTC time as seconds and fractional seconds since 1970-01-01 00:00:00.
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
void add_group(const std::string &name, Colors::Color color=Colors::nocolor, const std::string &description="")
Add another group to the logger. A group provides related manipulator for categorizing log messages...
common::FlexOstream glog
Access the Goby logger through this object.
The global namespace for the Goby project.
std::ostream & nocolor(std::ostream &os)
All text following this manipulator is uncolored (e.g. std::cout << green << "green" << nocolor << "u...