obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but that tree was gitignored, so a clone of this repository could not build the firmware it ships. It is now committed here as ordinary files in its own folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP bridge's signature verification (--trust) used on the bench. Nothing is fetched from or pushed to the colleague's repository; this repository and its remotes carry everything. The folder's own .gitignore keeps build output, downloaded components and private key material out, as it did there; the committed file set is identical to that repository's tracked files. The ESP32-C5 is still flashed from obu-firmware/, which only takes vanetza-idf from microbu-esp32c5/, so the two stay separate folders. FLASHING.md says how to take a newer version of the colleague's tree (copy it over the folder, rebuild, test, commit).
138 lines
4.4 KiB
C++
138 lines
4.4 KiB
C++
#include "cam_application.hpp"
|
|
#include <vanetza/btp/ports.hpp>
|
|
#include <vanetza/asn1/cam.hpp>
|
|
#include <vanetza/asn1/packet_visitor.hpp>
|
|
#include <vanetza/facilities/cam_functions.hpp>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
// This is a very simple CA application sending CAMs at a fixed rate.
|
|
|
|
using namespace vanetza;
|
|
using namespace vanetza::facilities;
|
|
using namespace std::chrono;
|
|
|
|
CamApplication::CamApplication(PositionProvider& positioning, Runtime& rt) :
|
|
positioning_(positioning), runtime_(rt), cam_interval_(seconds(1))
|
|
{
|
|
schedule_timer();
|
|
}
|
|
|
|
void CamApplication::set_interval(Clock::duration interval)
|
|
{
|
|
cam_interval_ = interval;
|
|
runtime_.cancel(this);
|
|
schedule_timer();
|
|
}
|
|
|
|
void CamApplication::set_station_id(std::uint32_t station_id)
|
|
{
|
|
station_id_ = station_id;
|
|
}
|
|
|
|
void CamApplication::print_generated_message(bool flag)
|
|
{
|
|
print_tx_msg_ = flag;
|
|
}
|
|
|
|
void CamApplication::print_received_message(bool flag)
|
|
{
|
|
print_rx_msg_ = flag;
|
|
}
|
|
|
|
CamApplication::PortType CamApplication::port()
|
|
{
|
|
return btp::ports::CAM;
|
|
}
|
|
|
|
void CamApplication::indicate(const DataIndication&, UpPacketPtr packet)
|
|
{
|
|
asn1::PacketVisitor<asn1::Cam> visitor;
|
|
std::shared_ptr<const asn1::Cam> cam = boost::apply_visitor(visitor, *packet);
|
|
|
|
std::cout << "CAM application received a packet with " << (cam ? "decodable" : "broken") << " content" << std::endl;
|
|
if (cam && print_rx_msg_) {
|
|
std::cout << "Received CAM contains\n";
|
|
print_indented(std::cout, *cam, " ", 1);
|
|
}
|
|
}
|
|
|
|
void CamApplication::schedule_timer()
|
|
{
|
|
runtime_.schedule(cam_interval_, std::bind(&CamApplication::on_timer, this, std::placeholders::_1), this);
|
|
}
|
|
|
|
void CamApplication::on_timer(Clock::time_point)
|
|
{
|
|
schedule_timer();
|
|
vanetza::asn1::Cam message;
|
|
|
|
ItsPduHeader_t& header = message->header;
|
|
header.protocolVersion = 2;
|
|
header.messageID = ItsPduHeader__messageID_cam;
|
|
header.stationID = station_id_;
|
|
|
|
const auto time_now = duration_cast<milliseconds>(runtime_.now().time_since_epoch());
|
|
uint16_t gen_delta_time = time_now.count();
|
|
|
|
CoopAwareness_t& cam = message->cam;
|
|
cam.generationDeltaTime = gen_delta_time * GenerationDeltaTime_oneMilliSec;
|
|
|
|
auto position = positioning_.position_fix();
|
|
if (!has_horizontal_position(position)) {
|
|
std::cerr << "Skip CAM generation without position fix" << std::endl;
|
|
return;
|
|
}
|
|
|
|
BasicContainer_t& basic = cam.camParameters.basicContainer;
|
|
basic.stationType = StationType_passengerCar;
|
|
copy(position, basic.referencePosition);
|
|
|
|
cam.camParameters.highFrequencyContainer.present = HighFrequencyContainer_PR_basicVehicleContainerHighFrequency;
|
|
|
|
BasicVehicleContainerHighFrequency& bvc = cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency;
|
|
bvc.heading.headingValue = 0;
|
|
bvc.heading.headingConfidence = HeadingConfidence_equalOrWithinOneDegree;
|
|
|
|
bvc.speed.speedValue = 0;
|
|
bvc.speed.speedConfidence = SpeedConfidence_equalOrWithinOneCentimeterPerSec;
|
|
|
|
bvc.driveDirection = DriveDirection_forward;
|
|
bvc.longitudinalAcceleration.longitudinalAccelerationValue = LongitudinalAccelerationValue_unavailable;
|
|
|
|
bvc.vehicleLength.vehicleLengthValue = VehicleLengthValue_unavailable;
|
|
bvc.vehicleLength.vehicleLengthConfidenceIndication = VehicleLengthConfidenceIndication_noTrailerPresent;
|
|
bvc.vehicleWidth = VehicleWidth_unavailable;
|
|
|
|
bvc.curvature.curvatureValue = 0;
|
|
bvc.curvature.curvatureConfidence = CurvatureConfidence_unavailable;
|
|
bvc.curvatureCalculationMode = CurvatureCalculationMode_yawRateUsed;
|
|
|
|
bvc.yawRate.yawRateValue = YawRateValue_unavailable;
|
|
|
|
std::string error;
|
|
if (!message.validate(error)) {
|
|
throw std::runtime_error("Invalid high frequency CAM: %s" + error);
|
|
}
|
|
|
|
if (print_tx_msg_) {
|
|
std::cout << "Generated CAM contains\n";
|
|
print_indented(std::cout, message, " ", 1);
|
|
}
|
|
|
|
DownPacketPtr packet { new DownPacket() };
|
|
packet->layer(OsiLayer::Application) = std::move(message);
|
|
|
|
DataRequest request;
|
|
request.its_aid = aid::CA;
|
|
request.transport_type = geonet::TransportType::SHB;
|
|
request.communication_profile = geonet::CommunicationProfile::ITS_G5;
|
|
|
|
auto confirm = Application::request(request, std::move(packet));
|
|
if (!confirm.accepted()) {
|
|
throw std::runtime_error("CAM application data request failed");
|
|
}
|
|
}
|