Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ find_package(zenohcxx REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(OpenMP REQUIRED)
find_package(protobuf CONFIG REQUIRED)
# find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)

set(PROTO_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
Expand Down
14 changes: 14 additions & 0 deletions proto/vehicle_gateway.proto
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ message EtaRequest
int64 request_id = 2;
double time = 3;
double fare = 4;
string status = 5;
}

message EtaResponse
Expand Down Expand Up @@ -100,6 +101,15 @@ message OrderUpdateStatusResponse



message TripCancelRequest{
string vin_number = 1;
int64 request_id = 2;
}

message TripCancelResponse{
bool success = 1;
string message = 2;
}


message GatewayCommand {
Expand All @@ -109,6 +119,8 @@ message GatewayCommand {
TripParkRequest trip_park = 3;
OrderUpdateLocationRequest order_update_location = 4;
OrderUpdateStatusRequest order_update_status = 5;
TripCancelRequest trip_cancel = 6;

}
}

Expand All @@ -123,6 +135,8 @@ message VehicleEvent {
StatusRequest status = 7;
ArriveRequest arrive = 8;
UpdateVehicleLocationRequest location = 9;
TripCancelResponse trip_cancel_ack = 10;

}
}

Expand Down
132 changes: 83 additions & 49 deletions src/AutowareApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@

using namespace std::chrono_literals;

namespace {

double calculate_fare(double distance_m, double time_seconds) {
constexpr double BASE_FARE = 5.0; // fixed base charge
constexpr double RATE_PER_KM = 2.0; // per kilometer
constexpr double RATE_PER_MIN = 0.5; // per minute

double distance_km = distance_m / 1000.0;
double time_min = time_seconds / 60.0;

double fare = BASE_FARE + (distance_km * RATE_PER_KM) + (time_min * RATE_PER_MIN);

spdlog::info("[AutowareApp] Fare: base={} + dist({:.2f}km * {}) + time({:.1f}min * {}) = {:.2f}",
BASE_FARE, distance_km, RATE_PER_KM, time_min, RATE_PER_MIN, fare);

return fare;
}

} // namespace

namespace autoware_agent {

AppHandles startAutowareApp(const std::string& yaml_path, const std::string& server_addr_in,
Expand Down Expand Up @@ -76,55 +96,69 @@ AppHandles startAutowareApp(const std::string& yaml_path, const std::string& ser
std::make_shared<vehicle_gateway::AutowareControllerTripAdapter>(h.controller_);

auto stream_client = std::make_shared<vehicle_gateway::VehicleGatewayStreamClient>(
"127.0.0.1:50051", trip_adapter.get(), eta_adapter.get(), loc_adapter.get(), "ORIN_NANO_001");

stream_client->set_handlers(
{.on_trip_init =
[ctrl = h.controller_, sc = stream_client](const vehicle_gateway::TripInitRequest& req) {
autoware_agent::GPSCoordinate start{.latitude = req.start_lat(),
.longitude = req.start_long()};
autoware_agent::GPSCoordinate goal{.latitude = req.end_lat(), .longitude = req.end_long()};
ctrl->queryEta(start, goal, [ctrl, sc](autoware_agent::EtaQueryResult r) {
if (!r.success_) {
spdlog::error("[AutowareApp] queryEta failed: {}", r.error_message_);
return;
}

double total_distance_m = r.pickup_leg_.distance_m_ + r.trip_leg_.distance_m_;
double total_eta_s = r.pickup_leg_.eta_seconds_ + r.trip_leg_.eta_seconds_;

sc->ReportEta(total_distance_m, total_eta_s);

ctrl->startTrip([](bool ok) {
if (!ok)
spdlog::error("[AutowareApp] startTrip rejected");
});
});
},

.on_trip_move =
[ctrl = h.controller_](const vehicle_gateway::TripMoveRequest&) {
ctrl->handleMoveCommand([](bool ok) {
if (!ok)
spdlog::error("[AutowareApp] move rejected");
});
},

.on_order_update_location =
[ctrl = h.controller_,
sc = stream_client](const vehicle_gateway::OrderUpdateLocationRequest& req) {
spdlog::info("[AutowareApp] OrderUpdateLocation request — vin={}", req.vin_number());

sc->ReportOrderUpdateLocationAck(true);

ctrl->getTripStatus([sc](autoware_agent::TripStatus status) {
spdlog::info("[AutowareApp] Reporting location: lat={} lon={}",
status.current_gps_.latitude, status.current_gps_.longitude);
sc->ReportLocation(status.current_gps_.latitude, status.current_gps_.longitude);
});
}

});
"127.0.0.1:50051", trip_adapter.get(), eta_adapter.get(), loc_adapter.get(), "ORIN_NANO_001",
h.cluster_bridge_->GetRequestId());

stream_client->set_handlers({
.on_trip_init =
[ctrl = h.controller_, sc = stream_client](const vehicle_gateway::TripInitRequest& req) {
autoware_agent::GPSCoordinate start{.latitude = req.start_lat(),
.longitude = req.start_long()};
autoware_agent::GPSCoordinate goal{.latitude = req.end_lat(), .longitude = req.end_long()};
ctrl->queryEta(start, goal, [ctrl, sc](autoware_agent::EtaQueryResult r) {
if (!r.success_) {
spdlog::error("[AutowareApp] queryEta failed: {}", r.error_message_);
return;
}

double total_distance_m = r.pickup_leg_.distance_m_ + r.trip_leg_.distance_m_;
double total_eta_s = r.pickup_leg_.eta_seconds_ + r.trip_leg_.eta_seconds_;
double fare = calculate_fare(r.trip_leg_.distance_m_, r.trip_leg_.eta_seconds_);
r.fare_ = fare;

sc->ReportEta(total_distance_m, total_eta_s, fare);

ctrl->startTrip([](bool ok) {
if (!ok)
spdlog::error("[AutowareApp] startTrip rejected");
});
});
},

.on_trip_move =
[ctrl = h.controller_](const vehicle_gateway::TripMoveRequest&) {
ctrl->handleMoveCommand([](bool ok) {
if (!ok)
spdlog::error("[AutowareApp] move rejected");
});
},

.on_order_update_location =
[ctrl = h.controller_,
sc = stream_client](const vehicle_gateway::OrderUpdateLocationRequest& req) {
spdlog::info("[AutowareApp] OrderUpdateLocation request — vin={}", req.vin_number());

sc->ReportOrderUpdateLocationAck(true);

ctrl->getTripStatus([sc](autoware_agent::TripStatus status) {
spdlog::info("[AutowareApp] Reporting location: lat={} lon={}",
status.current_gps_.latitude, status.current_gps_.longitude);
sc->ReportLocation(status.current_gps_.latitude, status.current_gps_.longitude);
});
},

.on_trip_cancel =
[ctrl = h.controller_, sc = stream_client](const vehicle_gateway::TripCancelRequest& req) {
spdlog::info("[AutowareApp] TripCancel received — reqId={} vin={}", req.request_id(),
req.vin_number());

ctrl->cancelTrip();

sc->ReportTripCancelAck(true);
sc->ReportStatus("CANCELLED");
},

});

h.controller_->setTripStateCallback([sc = stream_client](TripState, TripState next) {
if (next == TripState::WAITING_FOR_MOVE) {
Expand Down
5 changes: 5 additions & 0 deletions src/cluster_bridge/include/ClusterBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class ClusterBridge : public autoware_agent::ZenohPublisher {
int64_t& GetRequestId() {
return current_request_id_;
}

void SetRequestId(int64_t id) {
current_request_id_ = id;
}

boost::asio::io_context& GetIoContext() {
return io_context_;
}
Expand Down
1 change: 1 addition & 0 deletions src/gateway_bridge/include/ClusterBridgeProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ClusterEtaAdapter : public IEtaProvider {
.request_id = request_id_,
.time_seconds = static_cast<double>(state_.remaining_time_s),
.fare = 0.0 // Cloud should takeover pricing

};
}

Expand Down
1 change: 1 addition & 0 deletions src/gateway_bridge/include/TripStatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct EtaQueryResult {
LegEta pickup_leg_;
LegEta trip_leg_;
std::string error_message_;
double fare_{0.0};
};

struct HeldRoute {
Expand Down
51 changes: 47 additions & 4 deletions src/gateway_bridge/include/VehicleGatewayStreamClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,20 @@ struct StreamCommandHandlers {
std::function<void(const TripInitRequest&)> on_trip_init;
std::function<void(const TripMoveRequest&)> on_trip_move;
std::function<void(const OrderUpdateLocationRequest&)> on_order_update_location;
std::function<void(const TripCancelRequest&)> on_trip_cancel;
};

class VehicleGatewayStreamClient {
public:
VehicleGatewayStreamClient(const std::string& gateway_addr, ITripManager* trip_manager,
IEtaProvider* eta_provider, ILocationProvider* location_provider,
std::string vin)
std::string vin, int64_t& request_id)
: gateway_addr_(gateway_addr)
, trip_manager_(trip_manager)
, eta_provider_(eta_provider)
, location_provider_(location_provider)
, vin_(std::move(vin))
, current_request_id_(request_id)
, shutdown_(false) {
reconnect_thread_ = std::thread([this] { run_with_reconnect(); });
}
Expand Down Expand Up @@ -78,6 +80,14 @@ class VehicleGatewayStreamClient {
enqueue(ev);
}

void ReportTripCancelAck(bool success, const std::string& message = "") {
VehicleEvent ev;
auto* r = ev.mutable_trip_cancel_ack();
r->set_success(success);
r->set_message(message);
enqueue(ev);
}

void ReportOrderUpdateLocationAck(bool success, const std::string& message = "") {
VehicleEvent ev;
auto* r = ev.mutable_order_update_location_ack();
Expand All @@ -104,20 +114,21 @@ class VehicleGatewayStreamClient {
r->set_request_id(d.request_id);
r->set_time(d.time_seconds);
r->set_fare(d.fare);
r->set_status("COMPLETED");
enqueue(ev);
spdlog::info("[Stream] Eta event enqueued"); // ADD
}

void ReportEta(double distance_m, double time_seconds) {
void ReportEta(double distance_m, double time_seconds, double fare = 0.0) {
spdlog::info("[Stream] ReportEta called: distance={} time={}", distance_m,
time_seconds); // ADD
VehicleEvent ev;
auto* r = ev.mutable_eta();
r->set_vin_number(vin_);
r->set_request_id(eta_provider_->GetEta().request_id);
r->set_time(time_seconds);
r->set_fare(0.0);
// r->set_distance(distance_m);
r->set_fare(fare);
r->set_status("COMPLETED");
enqueue(ev);
spdlog::info("[Stream] Eta event enqueued"); // ADD
}
Expand Down Expand Up @@ -224,9 +235,35 @@ class VehicleGatewayStreamClient {
GatewayCommand cmd;
while (stream->Read(&cmd)) {
read_received.store(true);

// validate vin number
std::string cmd_vin;
if (cmd.has_trip_init()) {
cmd_vin = cmd.trip_init().vin_number();
} else if (cmd.has_trip_move()) {
cmd_vin = cmd.trip_move().vin_number();
} else if (cmd.has_trip_cancel()) {
cmd_vin = cmd.trip_cancel().vin_number();
} else if (cmd.has_trip_park()) {
cmd_vin = cmd.trip_park().vin_number();
} else if (cmd.has_order_update_location()) {
cmd_vin = cmd.order_update_location().vin_number();
} else if (cmd.has_order_update_status()) {
cmd_vin = cmd.order_update_status().vin_number();
}

if (cmd_vin != vin_) {
spdlog::warn(
"[StreamClient] Received command with mismatched VIN: expected {}, got {}. Ignoring "
"command.",
vin_, cmd_vin);
continue;
}

if (cmd.has_trip_init()) {
spdlog::info("[StreamClient] Received TripInit reqId={}", cmd.trip_init().request_id());
trip_manager_->SetActiveTripId(cmd.trip_init().request_id());
current_request_id_ = cmd.trip_init().request_id();
if (handlers_.on_trip_init)
handlers_.on_trip_init(cmd.trip_init());
} else if (cmd.has_trip_move()) {
Expand All @@ -239,6 +276,11 @@ class VehicleGatewayStreamClient {
cmd.order_update_location().vin_number());
if (handlers_.on_order_update_location)
handlers_.on_order_update_location(cmd.order_update_location());
} else if (cmd.has_trip_cancel()) {
spdlog::info("[StreamClient] Received TripCancel tripId={}",
cmd.trip_cancel().request_id());
if (handlers_.on_trip_cancel)
handlers_.on_trip_cancel(cmd.trip_cancel());
}
}

Expand Down Expand Up @@ -267,6 +309,7 @@ class VehicleGatewayStreamClient {
ILocationProvider* location_provider_;
std::string vin_;
StreamCommandHandlers handlers_;
int64_t& current_request_id_;

std::atomic<bool> shutdown_;
std::thread reconnect_thread_;
Expand Down
3 changes: 3 additions & 0 deletions src/gateway_bridge/src/TripController.cc
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ void TripController::cancel() {
trip_route_.reset();
status_ = TripStatus{};
route_received_ = false;
engaging_for_pickup_ = false;
current_route_state_.reset();

transitionTo(TripState::IDLE);
}

Expand Down
Loading