Skip to content

Feature/ppk scripts #186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
14c31be
uncommented existing logger and hardcoded a fix sender id for now
clanegge Jun 4, 2020
950c784
Refactoring of observation callback handler to handle any message type
clanegge Jun 11, 2020
0402c13
Created new MsgCallbackHandler for ephemeris and ionospheric delay
clanegge Jun 12, 2020
71f9ee0
Added ephemeris callback handler instance to ros receiver.
clanegge Jun 13, 2020
e684d38
Lock on file, if for some reason two callbacks would try to write at …
clanegge Jun 13, 2020
32c54cc
Tiny bug fix in cb_to_raw_obs_converter
clanegge Jun 13, 2020
47351a0
Cleaned up FileLogger initialization
clanegge Jun 13, 2020
7d98f7d
Some renaming
clanegge Jun 15, 2020
a416ac9
Add time-date filename to the log.
helenol Jun 29, 2020
331d2b1
Base station corrections too.
helenol Jun 30, 2020
d06cdc0
Merge branch 'master' into feature/message_logger
clanegge Sep 11, 2020
7528c26
Moved initialization of file logger into receiver_ros
clanegge Sep 14, 2020
e9a0fdf
Fixed attitude receiver not logging sbp messages
clanegge Sep 14, 2020
2f966e5
Added stop and start service server for observation logger
clanegge Sep 14, 2020
d5b3e86
Added script to convert from sbp binary file to rinex ppk_solution. A…
clanegge Sep 14, 2020
eccb6f0
Added fallback to Swisspos observations if base_*.sbp not found
clanegge Sep 14, 2020
32ec9e0
Fix: Script could not find swisspos files eventhough they where in fo…
clanegge Jul 7, 2021
c699034
Added script that computes mean position of base station
clanegge Jul 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion piksi_multi_cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ cs_add_library(${PROJECT_NAME}
src/sbp_callback_handler/ros_time_handler.cc
src/sbp_callback_handler/sbp_callback_handler.cc
src/sbp_callback_handler/sbp_callback_handler_factory.cc
src/sbp_callback_handler/sbp_observation_callback_handler.cc
)
target_link_libraries(${PROJECT_NAME} serialport stdc++fs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace piksi_multi_cpp {
/*
* Interface for a class that can handle observation callbacks
* from SBP.
* More message callbacks can be added here.
*/
class CallbackObservationInterface {
public:
Expand All @@ -18,6 +19,9 @@ class CallbackObservationInterface {
virtual void observationCallback(msg_glo_biases_t msg) = 0;
virtual void observationCallback(msg_obs_t_var msg) = 0;
virtual void observationCallback(msg_heartbeat_t msg) = 0;
virtual void observationCallback(msg_ephemeris_gps_t msg) = 0;
virtual void observationCallback(msg_ephemeris_glo_t msg) = 0;
virtual void observationCallback(msg_iono_t msg) = 0;
};

} // namespace piksi_multi_cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class CBtoRawObsConverter : public CallbackObservationInterface {
void observationCallback(msg_glo_biases_t msg) final;
void observationCallback(msg_obs_t_var msg) final;
void observationCallback(msg_heartbeat_t msg) final;
void observationCallback(msg_ephemeris_gps_t msg) final;
void observationCallback(msg_ephemeris_glo_t msg) final;
void observationCallback(msg_iono_t msg) final;

static std::shared_ptr<CBtoRawObsConverter> createFor(
const RawObservationInterface::Ptr& consumer, const uint16_t sbp_sender_id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define PIKSI_MULTI_CPP_OBSERVATIONS_FILE_OBSERVATION_LOGGER_H_

#include <piksi_multi_cpp/observations/cb_to_raw_obs_converter.h>
#include <mutex>

namespace piksi_multi_cpp {

Expand All @@ -16,13 +17,19 @@ class FileObservationLogger : public RawObservationInterface {
FileObservationLogger() {}
bool open(const std::string& filename);
void close();

// Return status wetherlogger is currently running
bool isLogging();

void insertObservation(const RawObservation& data) final;
~FileObservationLogger();

private:
// File pointer.
FILE* log_file_{nullptr}; // not using fstream, but raw file for performance.

// File pointer etc.
// mutex to lock file when writing
std::mutex file_mtx_;
};
} // namespace piksi_multi_cpp

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class ReceiverBaseStation : public ReceiverRos {
const piksi_rtk_msgs::PositionWithCovarianceStamped::Ptr& msg);
void setupBaseStationSampling();

uint16_t sbp_sender_id_ {0x42};
ros::ServiceServer resample_base_position_srv_;
ros::Subscriber ml_estimate_sub_;
ros::Subscriber receiver_state_sub_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
#define PIKSI_MULTI_CPP_RECEIVER_RECEIVER_ROS_H_

#include <ros/ros.h>
#include <std_srvs/SetBool.h>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include "piksi_multi_cpp/observations/file_observation_logger.h"
#include "piksi_multi_cpp/receiver/settings_io.h"
#include "piksi_multi_cpp/sbp_callback_handler/geotf_handler.h"
#include "piksi_multi_cpp/sbp_callback_handler/position_sampler.h"
#include "piksi_multi_cpp/sbp_callback_handler/sbp_callback_handler.h"
#include "piksi_multi_cpp/sbp_callback_handler/sbp_ephemeris_callback_handler.h"
#include "piksi_multi_cpp/sbp_callback_handler/sbp_observation_callback_handler.h"

namespace piksi_multi_cpp {
Expand All @@ -21,12 +24,26 @@ class ReceiverRos : public SettingsIo {

ReceiverRos(const ros::NodeHandle& nh, const Device::Ptr& device);

// set up user ID
bool init() override;

// Set up File Logger
bool startFileLogger();
bool startStopFileLoggerCallback(std_srvs::SetBool::Request& req,
std_srvs::SetBool::Response& res);

protected:
// ROS node handle in the correct receiver namespace.
ros::NodeHandle nh_;
// Service Server for starting or stopping file logger
ros::ServiceServer start_stop_logger_srv_;

// Sender ID of device
uint16_t sbp_sender_id_{0x42};

// Observation callbackhandlers
// Observation & Ephemeris callbackhandlers
std::unique_ptr<SBPObservationCallbackHandler> obs_cbs_;
std::unique_ptr<SBPEphemerisCallbackHandler> eph_cbs_;

// get vector valued string params
std::vector<std::string> getVectorParam(
Expand All @@ -36,6 +53,8 @@ class ReceiverRos : public SettingsIo {
GeoTfHandler::Ptr geotf_handler_;
// Averages the position over multiple ECEF messages.
PositionSampler::Ptr position_sampler_;
// File logger object
std::shared_ptr<FileObservationLogger> obs_logger_;

private:
// Relaying all SBP messages. Common for all receivers.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_EPHEMERIS_CALLBACK_HANDLER_H_
#define PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_EPHEMERIS_CALLBACK_HANDLER_H_
#include <piksi_multi_cpp/sbp_callback_handler/sbp_lambda_callback_handler.h>
#include <piksi_multi_cpp/sbp_callback_handler/sbp_msg_type_callback_handler.h>
#include <ros/ros.h>

namespace piksi_multi_cpp {

/*
* Subscribes to all 4 observation type callbacks simultaneously using
* LambdaCallbackHandlers and redirects these messages to all registered
* listeners.
*
*/
class SBPEphemerisCallbackHandler
: public SBPMsgTypeCallbackHandler {
public:
SBPEphemerisCallbackHandler(const ros::NodeHandle nh,
const std::shared_ptr<sbp_state_t>& state)
: SBPMsgTypeCallbackHandler(nh, state),
gps_ephemeris_handler_{getCallback<msg_ephemeris_gps_t>(),
SBP_MSG_EPHEMERIS_GPS, state},
glo_ephemeris_handler_{getCallback<msg_ephemeris_glo_t>(), SBP_MSG_EPHEMERIS_GLO,
state},
iono_delay_handler_{getCallback<msg_iono_t>(), SBP_MSG_IONO, state} {};

private:
/* Set up Lambda redirect callbacks for the three message types used for
* converting sbp to rinex, such that this class gets any of the three callbacks and can
* forward them to the observation listeners */
SBPLambdaCallbackHandler<msg_ephemeris_gps_t> gps_ephemeris_handler_;
SBPLambdaCallbackHandler<msg_ephemeris_glo_t> glo_ephemeris_handler_;
SBPLambdaCallbackHandler<msg_iono_t> iono_delay_handler_;
};
} // namespace piksi_multi_cpp

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_OBS_TYPE_CALLBACK_HANDLER_H_
#define PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_OBS_TYPE_CALLBACK_HANDLER_H_
#include <libsbp/sbp.h>
#include <ros/ros.h>
#include <piksi_multi_cpp/observations/callback_observation_interface.h>
#include <functional>

namespace piksi_multi_cpp {
namespace s = std::placeholders;

class SBPMsgTypeCallbackHandler {

public:
SBPMsgTypeCallbackHandler(const ros::NodeHandle nh,
const std::shared_ptr<sbp_state_t>& state)
: state_(state){};

/*
* Add listeners to message callbacks.
*/
void addObservationCallbackListener(const CallbackObservationInterface::Ptr& listener) {
if (listener.get()) {
listeners_.push_back(listener);
}
}

protected:
/*
* Convenience method to create a std::function for the callbackToListeners
* method.
* Implemented in header because of template.
*/
template <class SBPMsgStruct>
std::function<void(const SBPMsgStruct&, const uint8_t len)> getCallback() {
return std::bind(
&SBPMsgTypeCallbackHandler::callbackToListeners<SBPMsgStruct>, this,
s::_1, s::_2);
}

/*
* Forwards messages to observation listeners.
* Important: Only compiles if it is used only for sbp messages that can be
* consumed by the listeners, i.e. that have a viable observationCallback
* overload
* Implemented in header because of template.
*/
template <class SBPMsgStruct>
void callbackToListeners(const SBPMsgStruct& msg, const uint8_t len) {
// trigger callback on all listeners
for (const auto& listener : listeners_) {
listener->observationCallback(msg);
}
}

std::shared_ptr<sbp_state_t> state_;
std::vector<CallbackObservationInterface::Ptr> listeners_{};
};
} // namespace piksi_multi_cpp

#endif
Original file line number Diff line number Diff line change
@@ -1,62 +1,32 @@
#ifndef PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_OBSERVATION_CALLBACK_HANDLER_H_
#define PIKSI_MULTI_CPP_SBP_CALLBACK_HANDLER_SBP_OBSERVATION_CALLBACK_HANDLER_H_
#include <libsbp/observation.h>
#include <libsbp/sbp.h>
#include <libsbp/system.h>
#include <piksi_multi_cpp/observations/callback_observation_interface.h>
#include <piksi_multi_cpp/sbp_callback_handler/sbp_callback_handler.h>
#include <piksi_multi_cpp/sbp_callback_handler/sbp_lambda_callback_handler.h>
#include <piksi_multi_cpp/sbp_callback_handler/sbp_msg_type_callback_handler.h>
#include <ros/ros.h>
#include <memory>
#include <utility>

namespace piksi_multi_cpp {
namespace s = std::placeholders;

/*
* Subscribes to all 4 observation type callbacks simultaneously using
* LambdaCallbackHandlers and redirects these messages to all registered
* listeners.
*
*/
class SBPObservationCallbackHandler {
class SBPObservationCallbackHandler
: public SBPMsgTypeCallbackHandler {
public:
SBPObservationCallbackHandler(const ros::NodeHandle nh,
const std::shared_ptr<sbp_state_t>& state);

void addObservationCallbackListener(
const CallbackObservationInterface::Ptr& listener);
const std::shared_ptr<sbp_state_t>& state)
: SBPMsgTypeCallbackHandler(nh, state),
base_pos_handler_{getCallback<msg_base_pos_ecef_t>(),
SBP_MSG_BASE_POS_ECEF, state},
glo_bias_handler_{getCallback<msg_glo_biases_t>(), SBP_MSG_GLO_BIASES,
state},
obs_handler_{getCallback<msg_obs_t_var>(), SBP_MSG_OBS, state},
heartbeat_handler_{getCallback<msg_heartbeat_t>(), SBP_MSG_HEARTBEAT,
state} {};

private:
/*
* Convenience method to create a std::function for the callbackToListeners
* method.
* Implemented in header because of template.
*/
template <class SBPMsgStruct>
std::function<void(const SBPMsgStruct&, const uint8_t len)> getCallback() {
return std::bind(
&SBPObservationCallbackHandler::callbackToListeners<SBPMsgStruct>, this,
s::_1, s::_2);
}

/*
* Forwards messages to observation listeners.
* Important: Only compiles if it is used only for sbp messages that can be
* consumed by the listeners, i.e. that have a viable observationCallback
* overload
* Implemented in header because of template.
*/
template <class SBPMsgStruct>
void callbackToListeners(const SBPMsgStruct& msg, const uint8_t len) {
// trigger callback on all listeners
for (const auto& listener : listeners_) {
listener->observationCallback(msg);
}
}

std::shared_ptr<sbp_state_t> state_;
std::vector<CallbackObservationInterface::Ptr> listeners_{};
/* Set up Lambda redirect callbacks for the four message types used for
* corrections, such that this class gets any of the four callbacks and can
* forward them to the observation listeners */
Expand Down
6 changes: 4 additions & 2 deletions piksi_multi_cpp/launch/rover.launch
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
<param name="udp_observation_port"
value="26078"/> <!-- Port on which UDP broadcasts are received -->

<!-- Autoset ENU origin to startup position. Otherwise it waits for base station position. -->
<param name="set_enu_origin_from_current_pos" value="false" />
<param name="log_observations_to_file" value="true" />

<!-- Autoset ENU origin to startup position. Otherwise it waits for base station position. -->
<param name="set_enu_origin_from_current_pos" value="false" />
</node>
</group>
</launch>
30 changes: 30 additions & 0 deletions piksi_multi_cpp/src/observations/cb_to_raw_obs_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ void CBtoRawObsConverter::observationCallback(msg_heartbeat_t msg) {
finishMessage();
}

void CBtoRawObsConverter::observationCallback(msg_ephemeris_gps_t msg) {
// Repack into full SBP Message
startMessage();
sbp_send_message(&sbp_state_, SBP_MSG_EPHEMERIS_GPS, sbp_sender_id_, sizeof(msg),
reinterpret_cast<uint8_t*>(&msg),
&CBtoRawObsConverter::sbp_write_redirect);
// this triggers sbp_write_redirect
finishMessage();
}

void CBtoRawObsConverter::observationCallback(msg_ephemeris_glo_t msg) {
// Repack into full SBP Message
startMessage();
sbp_send_message(&sbp_state_, SBP_MSG_EPHEMERIS_GLO, sbp_sender_id_, sizeof(msg),
reinterpret_cast<uint8_t*>(&msg),
&CBtoRawObsConverter::sbp_write_redirect);
// this triggers sbp_write_redirect
finishMessage();
}

void CBtoRawObsConverter::observationCallback(msg_iono_t msg) {
// Repack into full SBP Message
startMessage();
sbp_send_message(&sbp_state_, SBP_MSG_IONO, sbp_sender_id_, sizeof(msg),
reinterpret_cast<uint8_t*>(&msg),
&CBtoRawObsConverter::sbp_write_redirect);
// this triggers sbp_write_redirect
finishMessage();
}

void CBtoRawObsConverter::startMessage() { buffer_msg_.clear(); }

void CBtoRawObsConverter::finishMessage() {
Expand Down
19 changes: 16 additions & 3 deletions piksi_multi_cpp/src/observations/file_observation_logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,40 @@ namespace piksi_multi_cpp {
bool FileObservationLogger::open(const std::string& filename) {
if (log_file_ != nullptr) return false; // can't open if another one is open.

log_file_ = fopen(filename.c_str(), "wb"); // open binary file.
// If filename already exist do not overwrite but append next free number to filename
int file_number = 0;
std::string unique_filename = filename + ".sbp";
while ((log_file_ = fopen(unique_filename.c_str(), "r"))) {
file_number++;
unique_filename = filename + "_" + std::to_string(file_number) + ".sbp";
fclose(log_file_);
}

log_file_ = fopen(unique_filename.c_str(), "wb"); // open binary file.
return (log_file_ == nullptr);
}

void FileObservationLogger::close() {
if (log_file_ != nullptr) {
fclose(log_file_);
log_file_ = nullptr;
}
}

bool FileObservationLogger::isLogging() { return (log_file_ != nullptr); }

void FileObservationLogger::insertObservation(
const piksi_multi_cpp::RawObservation& data) {

if (log_file_ != nullptr) {
file_mtx_.lock();
// write in chunks of 1byte for now. maybe blocked write might be a bit
// faster. But because we don't write large amounts of data, it probably
// doesn't matter too much
fwrite(data.data(), sizeof(uint8_t), data.size(), log_file_);
file_mtx_.unlock();
}
}

FileObservationLogger::~FileObservationLogger() { close(); }

}
} // namespace piksi_multi_cpp
Loading