Automatic Collision Notification (ACN)

Zendrive SDK contains a collision detection feature that uses your phone sensors to automatically detect if your car has been in a collision. Zendrive's collision detection is enabled by default when you integrate the SDK, and is active when a trip is in progress.

From Zendrive SDK v9.1.0 onwards, the speed threshold for both high and low-severity collisions (FNOL and ACN) has been reduced from 10 mph to 5 mph, for both iOS and Android. Note that this speed reduction does not affect the current barometer-based collision detection logic.

Collision Confidence Level Assignment

The collisionDetection API generates a single callback when it detects a collision. This callback contains info about the collision and can be used to initiate any emergency responses and automatic contact to loved ones.

Each detected collision is assigned a confidence level: HIGH or LOW. Based on the confidence measure, you may choose to implement custom business logic. The following recommended flow is the simplest course of action.

Zendrive SDK provides both a confidence level and a confidence number. Confidence numbers can be used to set numeric thresholds for different courses of action. An example is given below in our two-tier notification system.

In order to access the iOS collisionDetection API:

  • Entitlement and user permissions need to be enabled in applications.

  • Customer needs to add a boolean variable to enable the iOS crash detection feature in the pList file in the SDK setup.

Set up Collision Detection in your Application

Integrate the Zendrive SDK in your application (Full instructions: iOS | Android). To process callbacks from the collision:

//Swift
import ZendriveSDKSwift

public class ZendriveDelegateManager: NSObject, ZendriveDelegate {

...
    // Register for collision detected callback.
    func processAccidentDetected(_ accidentInfo: AccidentInfo) {
        print("Accident detected by Zendrive SDK.")
    }

...
}

Test for Collisions with the Mock Collision API

The mockCollision API provides the raiseMockAccident (iOS) andtriggerMockAccident (Android) functions to trigger a mock collision notification.

After setting up the SDK in collision detection mode, you can test your integration with these methods. This emulates a fake collision and invokes the onAccident handler in the ZendriveBroadcastReceiver.

@objc public static func raiseMockAccident(_ confidence: AccidentConfidence)

This requires the SDK to be set up and a trip to be in progress.

Crash Detection Feature for iOS

From Zendrive SDK v9.1.0 onwards, the collision notification feature is integrated with the iOS16 collisionDetection API, which facilitates the following actions:

When the Zendrive collision detection is triggered, the iOS 16 collisionDetection API checks for the collision status, and stores it, as follows:

  • The status will be NA if there is no iOS alert

  • Time, location and other information if a iOS collision alert exists.

The iOS collisionDetection API stores the collision data in the event.data field, which is uploaded to the Zendrive backend. Here's the latest developer documentation for iOS 16 containing integration information for the collision detection feature in iPhone 14.

Opt-in Program for Potential Collision

As an optional feature, Zendrive SDK is capable of delivering a quicker first notification of a potential collision. With this feature, an early notification is generated within seconds of a possible collision event. This callback may be used for a first notification of loss or to initiate emergency services.

The regular collision notification that is generated now serves to confirm or invalidate the quick notification. The following diagram demonstrates a sample flow for this system.

The confidence number labels (HIGH / MEDIUM / LOW) in the flowchart are representations. Each number represents a numeric threshold that can be adjusted in your application without any SDK changes from Zendrive. Sample thresholds: High = 90, Medium = 70, Low = <70. You can create as many thresholds as needed.

Activate the Potential Collision Program

  1. Implement the potentialAccident API call in your app.

  2. Call setImplementsMultipleAccidentCallbacks with true on your ZendriveConfiguration object.

  3. Contact Zendrive at [email protected] to opt-in to the program.

Implement the potentialAccident API call in iOS and Android using the functions below:

/// [Disabled by default]
    /// This callback is fired on the main thread when a potential accident is detected by the SDK during a drive.
    /// This is a preliminary callback of a potential collision. This collision is confirmed or invalidated by
    ///  `processAccidentDetected(_:)` callback.
    ///
    ///  To enable contact: [email protected](opens in new tab)
    ///
    /// - Parameter accidentInfo: Info about accident.
    ///
    @objc optional func processPotentialAccidentDetected(_ accidentInfo: AccidentInfo)

Testing Potential Collisions with the mockCollision API

The upgraded mockCollision API provides the ZendriveMockAccidentConfig (iOS) and ZendriveMockAccidentConfiguration (Android) classes to trigger a mock potential collision with the 2-stage notification system.

/// This class contains parameters required by `ZendriveTest.raiseMockAccidentUsingConfig(using:)` for testing accident flow.
@objc(ZDMockAccidentConfig) public class MockAccidentConfig : NSObject, NSCopying {
    /// This field specifies the confidence for the potential accident callback.
    ///
    /// Default value is `AccidentConfidence.high`.
    ///
    @objc public var potentialAccidentConfidence: AccidentConfidence
    /// This field specifies the confidence for the final accident callback.
    ///
    /// Default value is `AccidentConfidence.high`.
    ///
    @objc public var finalAccidentConfidence: AccidentConfidence
    /// This field specifies the confidence number for the potential accident callback.
    ///
    /// Default value is 70.
    @objc public var potentialAccidentConfidenceNumber: Int32
    /// This field specifies the confidence number for the final accident callback.
    ///
    /// Default value is 70.
    ///
    @objc public var finalAccidentConfidenceNumber: Int32
    /// This field specifies the callback delay (in seconds) between the potential and final accident callback.
    ///
    /// Default value is 20 seconds.
    ///
    @objc public var delayBetweenCallbacks: Int32
    /// This field specifies the vehicle type at the time of potential and final accident callback.
    ///
    /// Default value is `VehicleType.car`.
    ///
    @objc public var vehicleType: VehicleType

    /// This field specifies the collision severity at the time of potential and final accident callback.
    ///
    /// Default value is `CollisionSeverity.high`.
   ///
    @objc public var collisionSeverity: CollisionSeverity

    /// This field specifies the direction of impact at the time of potential accident callback and final accident callback.
    ///
    /// Default value is `DirectionOfImpact.unknown`.
    ///
    @objc public var directionOfImpact: DirectionOfImpact 
    
    /// This method causes the final callback to invalidate the potential callback.
    ///
    /// Invalidating final callbacks have confidence number as 0 and confidence as `AccidentConfidence.invalid`,
    /// signifying that the accident send out via the potential accident callback on further analysis has been reclassified as *not* being an accident.
    ///
    @objc public func invalidateFinalCallback()
}

The AccidentInfo Class

The AccidentInfo class in Android and the ZendriveAccidentInfo class in iOS contain key information about the collision. The Vehicle Type accident info object within the SDK collision callback contains a new parameter called vehicle type. It helps to identify the vehicle involved in the collision.

While the default return value is 'car’, if the vehicle involved in the accident is a motorcycle, then the value returned would be ‘motorcycle’. This accident vehicle type update is based on the motorcycle trip classifier output.

The motorcycle classifier has to be enabled in order for the Trip Type variable to display ‘motorcycle’ instead of ‘car’.

/// Wrapper for meta-information related to an accident detected by the SDK.
@objc(ZDAccidentInfo) public class AccidentInfo : NSObject {
    /// The unique Id of drive during which the accident occured
    @objc public var driveId: String
    /// The location of the accident.
    @objc public var accidentLocation: LocationPoint
    /// The timestamp of the accident in milliseconds since epoch.
    @objc public var timestamp: Int64
    /// The session that was in progress when the accident occured, if a session
    /// was started in the SDK.
    ///
    /// - SeeAlso: `Zendrive.startSession(_:)`
    @objc public var sessionId: String?
    /// The tracking id of the ongoing drive when the accident occured.
    ///
    /// - SeeAlso: `Zendrive.startManualDrive(_:completionHandler:)`
    @objc public var trackingId: String?
    /// The confidence of detected accident.
    @objc public var confidence: AccidentConfidence
    /// Measures an approximate precision of the detected collision. Ranges between 0 to 100.
    ///
    /// Note: A confidence number of 0 indicated that it was *not* an accident.
    /// 0 confidence number can be sent as a part of potential accident callback
    /// to invalidate the previous callback final accident callback for the same accident.
    /// 0 confidence number will never come as a part of potential accident callback.
    ///
    /// Checkout `MockAccidentConfig.invalidateFinalCallback()` to test this scenario during development.
    ///
    @objc public var confidenceNumber: Int32
    /// A unique identifier of this accident.
    @objc public var accidentId: String
    /// Vehicle type detected by SDK at the time of the accident.
    /// Default value is `VehicleType.car`.
    @objc public var vehicleType: VehicleType 
    /// This field specifies the collision severity at the time of potential and final accident callback.
    ///
    /// Default value is `CollisionSeverity.unknown`.
    @objc public var collisionSeverity: CollisionSeverity
    
    /// This field specifies the direction of impact at the time of potential accident callback and final accident callback.
    ///
    /// Default value is `DirectionOfImpact.unknown`.
    ///
    @objc public var directionOfImpact: DirectionOfImpact 

  /// Initializer for `AccidentInfo`.
    /// - Parameters:
    ///   - location: The location of the accident
    ///   - timestamp: The timestamp of the accident in milliseconds since epoch
    ///   - trackingId: The tracking id of the ongoing drive when the accident occured
    ///   - sessionId: The session that was in progress when the accident
    ///                  occurred, if a session was started in the SDK
    ///   - confidence: Confidence measure of the detected accident
    ///   - confidenceNumber: Confidence number of the detected accident
    ///   - accidentId: A unique identifier of this accident
    ///   - driveId: The unique Id of drive during which the accident occured
    ///   - vehicleType: Vehicle type detected by SDK at the time of the accident
    ///   - collisionSeverity: Collision Severity detected by SDK at the time of the accident
    ///   - directionOfImpact: Direction Of Impact detected by SDK at the time of the accident
    /// - Returns: `AccidentInfo` object
    @objc public init(location:LocationPoint, 
                      timestamp: Int64, 
                      trackingId: String?, 
                      sessionId: String?, 
                      confidence: AccidentConfidence, 
                      confidenceNumber: Int32, 
                      accidentId: String, 
                      driveId: String, 
                      vehicleType: VehicleType, 
                      collisionSeverity: CollisionSeverity, 
                      directionOfImpact: DirectionOfImpact)
    
    /// Returns a dictionary that represents the `AccidentInfo` object.
    @objc public func toDictionary() -> [AnyHashable : Any]
    /// Returns a JSON formatted string that represents the `AccidentInfo` object.
    @objc public func toJson() -> String
}

The generated collision data has the following structure. This information is useful for business logic, for example, the accidentLocation field is crucial to relay to emergency services.

{
  "driverId" : "sample",
  "accidentLocation" : {"timestamp": 1559065297688, 
                        "latitude": 80.133, 
                        "longitude": 15.12343 },
  "timestamp": 1559065297688,
  "confidence": 0,
  "confidenceNumber": 34,
  "accidentId": "wii8uwju",
  "vehicleType":0,
  "collisionSeverity":0
}

Was this helpful?