The problem
AUTOSAR Adaptive applications communicate through ara::com, which hides the transport behind generated proxy and skeleton classes. Commercial Adaptive stacks are not freely available to students, but the pattern itself can be built and studied. This project implements the proxy and skeleton pattern for a perception service on open-source SOME/IP, so students understand what generated code does and what it costs.
Objectives
- Describe the ara::com service model: proxies, skeletons, events, methods, fields and FindService.
- Model the perception service interface as an ARXML-style service interface description.
- Implement skeleton and proxy classes over vsomeip with a serialisation layer.
- Support event polling and callback modes on the proxy side.
- Measure latency and serialisation cost against payload size and rate.
What you need
Tools and toolboxes
- C++17 with CMake — Implements the skeleton, proxy and binding classes.
- vsomeip (COVESA) — SOME/IP transport and Service Discovery underneath the ara::com-style API.
- Python with OpenCV and Ultralytics YOLO — Runs a detector on recorded video to produce realistic object lists for the skeleton.
- Wireshark — Confirms the SOME/IP messages produced by the binding.
- Vector DaVinci Adaptive or similar (industry reference only) — Named as the kind of tool that generates proxy and skeleton code from ARXML in industry; not required for the project.
Software
- Ubuntu Linux
- C++17 toolchain with CMake
- vsomeip
- Python with Ultralytics YOLO and OpenCV
- Wireshark
Extra parts and data
- Recorded dashcam footage or a public driving dataset such as KITTI or BDD100K — Provides realistic object counts and rates for the perception events instead of synthetic constant payloads.
Key concepts
- Proxy and skeleton
- The skeleton is the server-side class an application fills in to provide a service; the proxy is the client-side class that represents a remote service instance and exposes its events and methods.
- FindService and StartFindService
- ara::com offers one-shot search for service instances and a continuous search that calls a handler whenever instances appear or disappear.
- Event sample cache
- A proxy subscribes with a maximum sample count; received samples are stored and the application fetches them with GetNewSamples, either by polling or from a receive handler.
- Future-based methods
- Method calls on a proxy return a future, so the caller can wait, poll or attach a continuation instead of blocking.
Step-by-step guide
- 1
Define the perception service interface
Specify a PerceptionObjects service interface with an event ObjectList (up to 64 objects, each with class ID, confidence, 2D box and an estimated distance), a method SetConfidenceThreshold returning the applied value and a field FrameRate with getter and notifier. Write it as a simplified ARXML-style XML file with SERVICE-INTERFACE, EVENTS, METHODS and FIELDS elements, and add a deployment section mapping it to SOME/IP service, event and method IDs.
Checkpoint: An interface description file that lists every element with data types and SOME/IP IDs.
- 2
Design the class structure
Draw the class diagram: a PerceptionObjectsSkeleton with OfferService, StopOfferService, an event member with Send and Allocate, and a virtual method handler; a PerceptionObjectsProxy with static FindService and StartFindService, an event member with Subscribe, SetReceiveHandler and GetNewSamples, and a method returning std::future. Keep a separate binding layer that maps these calls to vsomeip, so the application never touches vsomeip directly. Mirror the naming used in the ara::com specification so the mapping is clear to reviewers.
Checkpoint: A class diagram and header files that compile with empty implementations.
- 3
Write the serialisation layer
Implement serialise and deserialise functions for the object struct and the list, using big-endian byte order and a length field for the dynamic array, consistent with SOME/IP serialisation rules for your chosen options. Write unit tests that round-trip random lists of 0 to 64 objects and compare every field. Measure serialisation time per list size with std::chrono over many iterations.
Checkpoint: Round-trip unit tests pass and a table of serialisation time against list size is recorded.
- 4
Implement the skeleton binding
Implement OfferService by creating the vsomeip application, offering the service and event, and registering a message handler that decodes SetConfidenceThreshold requests, calls the user's virtual handler and returns the result. Implement the event Send to serialise and notify subscribers. Implement the field so a new FrameRate value is sent as a notification and returned by its getter. Handle the case where no subscriber is present.
Checkpoint: A test skeleton offers the service and Wireshark shows OfferService and event notifications.
- 5
Implement the proxy binding
Implement FindService and StartFindService on top of the vsomeip availability handler, returning handles that identify instances. Implement event Subscribe with a maximum sample count, a bounded sample queue, SetReceiveHandler and GetNewSamples. Implement the method call by sending a request and resolving a std::promise when the response with the matching session ID arrives, with a timeout that sets an error. Log every offered element at start-up so missing configuration shows immediately.
Checkpoint: A test proxy finds the service, receives events by callback and by polling, and gets method results through futures.
- 6
Connect a real detector
Run Ultralytics YOLO on recorded driving video in a Python process and pass detections to the C++ skeleton through a local socket or shared file, or run the detector offline and replay its outputs with original timestamps. Estimate distance from box height with a simple pinhole assumption and label it as approximate. The skeleton publishes ObjectList at the video frame rate.
Checkpoint: The proxy application prints live object lists that match detections drawn on the video frames.
- 7
Test service lifecycle
Start the proxy before the skeleton and confirm StartFindService reports the instance when it appears. Stop and restart the skeleton and check that the proxy handler reports the loss and the return, and that subscriptions are re-established. Call SetConfidenceThreshold while the skeleton is down and check the future returns an error after the timeout instead of hanging. Run each lifecycle case several times, because timing-dependent bugs often appear only occasionally.
Checkpoint: Lifecycle test log showing correct availability changes, re-subscription and method timeout behaviour.
- 8
Measure performance
Measure end-to-end event latency from Send to the receive handler for list sizes of 1, 16 and 64 objects at 10, 30 and 60 Hz, with 5,000 samples each. Separate serialisation, transport and deserialisation time where possible. Measure method round-trip time. Record CPU use of both processes. Compare callback mode with polling at a fixed period and explain the latency difference.
Checkpoint: Latency tables and plots for each size and rate, plus callback versus polling comparison.
- 9
Compare with the standard
List which parts of the ara::com specification your implementation covers and which it omits, for example generated code, E2E protection, security and the full error model. Explain how a commercial Adaptive stack would generate the same classes from ARXML and add these features. Discuss how your measured costs would scale with a production stack. Use the same interface file so the comparison stays tied to what you actually built and measured.
Checkpoint: A coverage table mapping implemented features to the ara::com concepts with gaps clearly stated.
- 10
Report
Document the interface description, class design, binding, serialisation, tests and performance results. Include sequence diagrams for FindService, subscription and a method call. State limitations: a hand-written binding, not a certified Adaptive platform, and approximate distance estimates. Provide build scripts and recorded data references so results can be reproduced. Add a short guide on extending the interface with a new event, listing every file that must change.
Checkpoint: A report with diagrams, code and reproducible measurements.
Testing & validation
- Serialisation round-trip tests for all list sizes.
- Service lifecycle tests: late start, restart and method timeout.
- Event latency for each list size and rate over 5,000 samples.
- Wireshark confirmation that messages match the deployment IDs.
Expected results
A working ara::com-style proxy and skeleton for a perception service over vsomeip, carrying real detector output, with measured latency and serialisation costs and a clear map to the AUTOSAR Adaptive concepts.
Research angle for your M.Tech thesis
Research questions: how do serialisation and transport costs of a service-oriented perception interface scale with object count and rate, and where is the crossover at which a zero-copy or shared-memory binding becomes necessary? Metrics: median and 99th-percentile latency, CPU per message and maximum sustainable rate. Baselines: raw vsomeip and ROS 2 topics on the same host. A careful, reproducible cost model for service-based perception interfaces, with code released, can support a workshop or conference paper on SDV middleware.
Take it further
- Write a small generator that produces the proxy and skeleton code from the interface file.
- Add an E2E protection header to events and test corruption detection.
- Add a zero-copy local transport for same-host communication and compare latency.
- Bridge the service into ROS 2 and compare latency with ROS 2 topics.
Viva and review questions
What does the skeleton do that the application does not?
It handles offering the service, receiving and decoding requests, and serialising and sending events, so the application only implements the service logic.
Why do proxy methods return futures?
Remote calls take time and can fail, so a future lets the caller decide whether to wait, poll or continue, and carries an error if the call times out.
Why limit the event sample cache?
It bounds memory and makes overload behaviour predictable; if the application reads too slowly, old samples are dropped rather than memory growing.
Is your implementation an AUTOSAR Adaptive platform?
No. It implements the ara::com communication pattern for study; a compliant platform adds generated code, the full API, security, E2E and other functional clusters.
Learn it at DIYguru
These DIYguru courses and programmes teach what this project needs.
