Keep vanetza-idf in obu-firmware, so a plain clone builds the firmware

obu-firmware builds against the vanetza-idf C-ITS library, which until now
came from the colleague's microbu-esp32c5 tree beside the repository and was
not tracked here, so a clone of this repository could not build the firmware
it ships. The library alone is now part of obu-firmware, as
obu-firmware/external/vanetza-idf: their external/vanetza-idf at commit
cf4b99f, unchanged (9775 files; see its PROVENANCE.md). CMake takes it from
there by default; -DVANETZA_IDF_DIR still points the build elsewhere.

The rest of the colleague's tree (their own VAM firmware, PKI tooling,
station-link Python tools, the V2X2MAP bridge) stays out of this repository
and gitignored; nothing is pushed to their repository. NOTES.md, docs/06,
TODO.md and the pcap verifier's usage line point at the new location.
This commit is contained in:
Ashin Walpola
2026-09-24 10:56:05 +02:00
parent 2f60623e18
commit d107534eb2
9781 changed files with 1560475 additions and 17 deletions
@@ -0,0 +1,5 @@
add_vanetza_component(gnss nmea.cpp)
target_link_libraries(gnss PUBLIC Boost::date_time)
add_test_subdirectory(tests)
+155
View File
@@ -0,0 +1,155 @@
#include "nmea.hpp"
#include "wgs84point.hpp"
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/format.hpp>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <sstream>
namespace vanetza
{
namespace nmea
{
using namespace vanetza::units;
/**
* Print latitude data in BBBB.BBBB, b format.
* BBBB.BBBB are degrees and minutes (ddmm.mm)
* b is N or S
*/
void print_latitude(std::ostream& os, const Wgs84Point& point)
{
double degrees = point.lat.value();
double minutes = std::modf(std::abs(degrees), &degrees) * 60.0;
os << boost::format("%02d%07.4f") % degrees % minutes;
os << "," << (point.lat.value() >= 0.0 ? "N" : "S");
}
/**
* Print longitude data in LLLL.LLLL, l format.
* LLLL.LLLL are degrees and minutes (ddmm.mm)
* l is E or W
*/
void print_longitude(std::ostream& os, const Wgs84Point& point)
{
double degrees = point.lon.value();
double minutes = std::modf(std::abs(degrees), &degrees) * 60.0;
os << boost::format("%02d%07.4f") % degrees % minutes;
os << "," << (point.lon.value() >= 0.0 ? "E" : "W");
}
namespace detail
{
struct latitude
{
latitude(const Wgs84Point& p) : point(p) {}
friend std::ostream& operator<<(std::ostream& os, const latitude& lat)
{
print_latitude(os, lat.point);
return os;
}
const Wgs84Point& point;
};
struct longitude
{
longitude(const Wgs84Point& p) : point(p) {}
friend std::ostream& operator<<(std::ostream& os, const longitude& lon)
{
print_longitude(os, lon.point);
return os;
}
const Wgs84Point& point;
};
} // namespace detail
detail::latitude latitude(const Wgs84Point& p) { return detail::latitude(p); }
detail::longitude longitude(const Wgs84Point& p) { return detail::longitude(p); }
/**
* Finish NMEA sentence with *XX where XX is the calculated checksum
* \param smsg NMEA sentence with leading $ but without trailing *XX
* \return finished NMEA sentence
*/
std::string finish(std::stringstream& smsg)
{
std::string msg = smsg.str();
unsigned sum = checksum(++msg.begin(), msg.end());
msg += boost::str(boost::format("*%02X") % static_cast<unsigned>(sum));
return msg;
}
std::string gprmc(const time& ptime, const Wgs84Point& wgs84,
NauticalVelocity ground_speed, TrueNorth heading)
{
/**
* Magnetic declination for central europe is about 1 degree east (2010), see this map for reference:
* http://upload.wikimedia.org/wikipedia/commons/d/dd/World_Magnetic_Model_Main_Field_Declination_D_2010.png
*/
const double magnetic_angle = 1.0;
const char magnetic_direction = 'E';
std::stringstream smsg;
smsg << std::uppercase << std::fixed;
auto* tfacet = new boost::posix_time::time_facet("%H%M%S");
auto* dfacet = new boost::gregorian::date_facet("%d%m%y");
smsg.imbue(std::locale(smsg.getloc(), tfacet));
smsg.imbue(std::locale(smsg.getloc(), dfacet));
smsg << "$GPRMC,";
smsg << ptime << ","; // HHMMSS
smsg << static_cast<char>(RMCStatus::Valid) << ",";
smsg << latitude(wgs84) << "," << longitude(wgs84) << ",";
smsg << std::setprecision(1) << ground_speed.value() << ","; // GG.G
smsg << std::setprecision(1) << std::fmod(heading.value(), 360.0) << ","; // RR.R
smsg << ptime.date() << ","; // DDMMYY
smsg << std::setprecision(1) << magnetic_angle << "," << magnetic_direction << ","; // M.M, E/W
smsg << static_cast<char>(FAAMode::Autonomous);
return finish(smsg);
}
std::string gpgga(const time& ptime, const Wgs84Point& wgs84, Quality quality, Length hdop)
{
const unsigned satellites = 6; // Arbitrary number of used GPS satellites
const double height = 0.0; // SUMO map is flat
const double separation = 0.0; // Geoidal separation, can it be calculated?
std::stringstream smsg;
smsg << std::uppercase << std::fixed;
auto* facet = new boost::posix_time::time_facet("%H%M%s");
smsg.imbue(std::locale(smsg.getloc(), facet));
smsg << "$GPGGA,";
smsg << ptime << ","; // HHMMSS.ss
smsg << latitude(wgs84) << "," << longitude(wgs84) << ",";
smsg << static_cast<std::underlying_type<Quality>::type>(quality) << ","; // Q
smsg << std::setw(2) << std::setfill('0') << satellites << ","; // NN
smsg << std::setprecision(1) << hdop.value() << ","; // D.D
smsg << std::setprecision(1) << height << ",M,"; // H.H, h
smsg << std::setprecision(1) << separation << ",M,"; // G.G, g
smsg << ","; // AA, RRRR (both optional)
return finish(smsg);
}
uint8_t checksum(std::string::const_iterator begin, std::string::const_iterator end)
{
assert(begin <= end);
uint8_t sum = 0;
for (; begin != end; ++begin) {
sum ^= *begin;
}
return sum;
}
} // namespace nmea
} // namespace vanetza
+58
View File
@@ -0,0 +1,58 @@
#ifndef NMEA_HPP_EJIHQ65L
#define NMEA_HPP_EJIHQ65L
#include <vanetza/units/angle.hpp>
#include <vanetza/units/velocity.hpp>
#include <vanetza/units/length.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <cstdint>
#include <string>
namespace vanetza
{
// forward declaration
struct Wgs84Point;
namespace nmea
{
typedef boost::posix_time::ptime time;
enum class Quality
{
Unavailable = 0,
GPS = 1,
DGPS = 2,
PPS = 3,
RTK = 4,
Float_RTK = 5,
Estimated = 6,
Manual = 7,
Simulation = 8
};
enum class RMCStatus : char
{
Warning = 'V',
Valid = 'A'
};
enum class FAAMode : char
{
Autonomous = 'A',
Differential = 'D',
Estimated = 'E',
Manual = 'M',
Simulated = 'S',
Invalid = 'N'
};
std::string gprmc(const time&, const Wgs84Point&, units::NauticalVelocity ground, units::TrueNorth heading);
std::string gpgga(const time&, const Wgs84Point&, Quality, units::Length hdop);
uint8_t checksum(std::string::const_iterator, std::string::const_iterator);
} // namespace nmea
} // namespace vanetza
#endif /* NMEA_HPP_EJIHQ65L */
@@ -0,0 +1,5 @@
include(UseGTest)
configure_gtest_directory(LINK_LIBRARIES gnss)
add_gtest(NMEA nmea.cpp)
@@ -0,0 +1,37 @@
#include <gtest/gtest.h>
#include <vanetza/gnss/nmea.hpp>
#include <vanetza/gnss/wgs84point.hpp>
#include <string>
using namespace vanetza;
TEST(NMEA, gprmc) {
using namespace boost::posix_time;
using namespace boost::gregorian;
nmea::time time(date(2013, 12, 5), time_duration(10, 32, 15));
Wgs84Point position(49.8234932 * units::degree, -12.5343 * units::degree);
units::NauticalVelocity speed(9.358 * units::metric::knots);
units::TrueNorth heading(273.4 * units::true_north_degrees);
std::string rmc = nmea::gprmc(time, position, speed, heading);
EXPECT_EQ("$GPRMC,103215,A,4949.4096,N,1232.0580,W,9.4,273.4,051213,1.0,E,A*33", rmc);
}
TEST(NMEA, gpgga) {
using namespace boost::posix_time;
using namespace boost::gregorian;
nmea::time time(date(2013, 11, 30), time_duration(19, 55, 59));
Wgs84Point position(-0.34 * units::degree, 165.39999 * units::degree);
nmea::Quality quality = nmea::Quality::DGPS;
units::Length hdop = 3.532 * units::si::meters;
std::string gga = nmea::gpgga(time, position, quality, hdop);
EXPECT_EQ("$GPGGA,195559.000000,0020.4000,S,16523.9994,E,2,06,3.5,0.0,M,0.0,M,,*4E", gga);
}
TEST(NMEA, checksum) {
std::string s = {0, 1, 2, 3, 4, 5};
auto c = nmea::checksum(s.begin(), s.end());
EXPECT_EQ(c, 0x01);
}
@@ -0,0 +1,20 @@
#ifndef WGS84POINT_HPP_GAHDJKCG
#define WGS84POINT_HPP_GAHDJKCG
#include <vanetza/units/angle.hpp>
namespace vanetza
{
struct Wgs84Point
{
typedef units::GeoAngle angle_type;
Wgs84Point(angle_type latitude, angle_type longitude) : lat(latitude), lon(longitude) {}
angle_type lat;
angle_type lon;
};
} // namespace vanetza 
#endif /* WGS84POINT_HPP_GAHDJKCG */