1 # Copyright (c) 2019-2020 NVIDIA CORPORATION. All rights reserved.
3 @page localization_usecase1 Camera Localization
4 @note SW Release Applicability: This tutorial is applicable to modules in **NVIDIA DRIVE Software** releases.
7 The workflow of localization is as follows:
8 * Initialize the @ref localization_mainsection module and its dependencies, including the @ref egomotion_mainsection module.
9 * While precise position is needed:
10 * Update the @ref egomotion_mainsection module as raw GPS/IMU/CAN measurements are available.
11 * Obtain and prepare sensor data:
12 * Perform camera based detections (lane detection, pole detection, sign detection, etc.).
13 * Obtain an approximate rig position and orientation in absolute WGS84 and ENU coordinates using the @ref egomotion_mainsection module.
14 * Obtain a relative rig pose transformation between the previous timestamp of localization invocation to the current camera
15 timestamp using the @ref egomotion_mainsection module.
16 * Invoke the localization algorithm and obtain localized results.
17 * When done, release the acquired resources.
19 Below is the general structure for usage, for the full implementation refer to @ref dwx_maps_localization_sample.
23 Before the @ref localization_mainsection module can be used, all prerequisite modules need to be initialized.
24 Prerequisite modules include @ref maps_mainsection, @ref rig_mainsection,
25 @ref landmarks_mainsection, and @ref egomotion_mainsection.
27 The following snippet initializes the @ref maps_mainsection.
30 dwMaps_initialize(&m_map, mapFilePath, m_context);
33 The snippet below initializes the @ref rig_mainsection module.
36 dwRig_initializeFromFile(&m_rigConfig, m_context, rigFile);
39 The next snippet initializes the @ref landmarks_mainsection module.
41 dwMaps_initialize(&m_map, mapFilePath, m_context);
42 dwMapNetParams mapNetParams{};
43 dwMapNet_initDefaultParams(&mapNetParams, DW_MAPNET_TYPE_SEGMENTATION, m_context);
44 dwMapNet_initialize(&m_mapNet, &mapNetParams, m_context);
45 dwLandmarkDetectorParams landmarkParams;
46 dwLandmarkDetector_initializeDefaultParams(&landmarkParams, m_cameraWidth, m_cameraHeight));
47 dwLandmarkDetector_initializeFromMapNet(&m_landmarkDetector, m_mapNet, landmarkParams, m_cameraWidth, m_cameraHeight, m_context);
49 The @ref landmarks_mainsection module detects lane lines, road boundaries, and roadside poles. For users who wish to include road sign and traffic light detections, the
50 @ref object_mainsection modules should also be initialized. This module can be initialized in a similar manner
51 to the @ref landmarks_mainsection module; a detailed description is provided in @ref object_usecase1.
53 The snippet below initializes the @ref egomotion_mainsection module with example parameters. Both the relative and global (GNSS dependent)
54 variants are required.
57 // relative egomotion parameters
58 dwEgomotionParameters relativeEgomotionParams = {};
59 dwEgomotion_initParamsFromRig(&relativeEgomotionParams, m_rigConfig, m_imuSensorName, nullptr, m_canSensorName);
60 relativeEgomotionParams.motionModel = DW_EGOMOTION_IMU_ODOMETRY;
61 relativeEgomotionParams.automaticUpdate = true; // update automatically
62 relativeEgomotionParams.historySize = 1000;
64 dwEgomotion_initialize(&m_egomotion, &relativeEgomotionParams, m_context);
66 // global egomotion parameters
67 dwGlobalEgomotionParameters globalEgomotionParams = {};
68 dwGlobalEgomotion_initParamsFromRig(&globalEgomotionParams, m_rigConfig, m_gpsSensorName);
70 dwGlobalEgomotion_initialize(&m_globalEgomotion, &globalEgomotionParams, m_context);
73 Once all dependencies are set up, the @ref localization_mainsection module can be initialized.
76 dwLocalizationParameters locParams{};
77 dwLocalization_initParamsFromRig(&m_params, m_rigConfig,
78 m_numCameras, m_cameraIndices);
79 dwLocalization_initialize(&m_localizer, m_map, &locParams, m_context);
82 Once the @ref localization_mainsection module is initialized, the HD map can be changed.
84 dwLocalization_setMap(m_map, m_localizer);
87 ## Data Reading and Preparation
88 Localization should be called on a per camera-frame basis. Each call requires visual features, a WGS84 position,
89 an ENU orientation, and a relative transformation from the previous camera frame timestep to the current camera frame timestep.
90 Regarding visual features, lane and road boundaries are required, while roadside poles, traffic signs, and traffic lights are optional inputs that improve localization accuracy.
91 Position and orientation inputs need to be measured at or interpolated to the exact timestamp of the camera frame; the @ref egomotion_mainsection module
92 offers this functionality.
94 The snippet below shows how to detect lanes, road boundaries, and poles using the @ref landmarks_mainsection module.
95 Although not shown here, traffic signs and traffic lights can be detected using the @ref object_mainsection module.
98 dwLaneDetection lanes{};
99 dwLandmarkDetection poles{};
100 dwRoadmarkDetection roadmarks{};
101 dwLandmarkDetector_detectLandmarks(&lanes, &poles, &roadmarks, cameraFrame, m_landmarkDetector)
104 The @ref egomotion_mainsection modules have the ability to track global and relative position
105 and orientation. Every time new GPS, IMU or CAN data is available, the modules should be updated.
106 The snippet below illustrates the steps needed to update the @ref egomotion_mainsection objects with new measurements.
107 Refer to @ref egomotion_usecase1 and @ref egomotion_usecase2 for more details.
110 // CAN and IMU data required for relative egomotion
114 ... // Parse the CAN message and get vehicle state
116 dwEgomotion_addVehicleState(&currVehicleState, m_egomotion)
119 if (hasIMUMeasurement())
121 dwEgomotion_addIMUMeasurement(&imuFrame, m_egomotion);
124 // GPS data and relative egomotion required for global egomotion
126 if (hasGPSMeasurement())
128 dwGlobalEgomotion_addGPSMeasurement(&gpsFrame, m_globalEgomotion);
132 // Update global egomotion module with latest relative egomotion state
133 dwEgomotionResult state = {};
134 dwEgomotionUncertainty uncertainty = {};
136 if (dwEgomotion_getEstimation(&state, m_egomotion) == DW_SUCCESS &&
137 dwEgomotion_getUncertainty(&uncertainty, m_egomotion) == DW_SUCCESS)
139 dwGlobalEgomotion_addRelativeMotion(&state, &uncertainty, m_globalEgomotion);
145 When a new camera frame is captured, the user queries the global @ref egomotion_mainsection object for the vehicle's
146 WGS-84 position and ENU orientation. Additionally, the user queries the relative egomotion object for the relative motion.
147 When querying any of the @ref egomotion_mainsection modules, it is important to ensure that the reported estimates are valid. Depending on the internal
148 state of an egomotion object, estimates may not be available. The @ref localization_mainsection
149 module assumes all inputs are valid, and therefore, invalid measurements should not be passed in.
151 The snippet below highlights the steps necessary for obtaining correct measurements from the @ref egomotion_mainsection modules:
154 // Obtain relative transform from egomotion
155 dwTransformation3f currToPrev = {};
156 dwStatus relativeEgoStatus = dwEgomotion_computeRelativeTransformation(&currToPrev, nullptr,
157 cameraTimestamp, m_prevCameraTimestamp,
160 // Obtain global orientation and position from egomotion
161 dwGlobalEgomotionResult globalEgoResult = {};
162 dwGlobalEgomotionUncertainty globalEgoUncertainty = {};
163 dwStatus globalEgoStatus = dwGlobalEgomotion_computeEstimate(&globalEgoResult, &globalEgoUncertainty,
164 cameraTimestamp, m_globalEgomotion);
165 bool relativeEgomotionValid = (relativeEgoStatus == DW_SUCCESS);
166 bool globalEgomotionValid = (globalEgoStatus == DW_SUCCESS) && globalEgoResult.validPosition && globalEgoResult.validOrientation;
169 @note In cases where the estimates from @ref egomotion_mainsection are invalid or unavailable, it is best to clean the internal state
170 of the @ref localization_mainsection module by calling dwLocalization_reset() and resume localization only when valid global and relative
171 estimates are available.
174 Once the input data is ready, the localization algorithm can be invoked. As a localization module instance maintains
175 an internal state of previous positions and detections, the module should be repeatedly invoked over a sequence of data frames.
178 dwLocalizationResult locResult{};
179 dwLocalization_localize(&locResult,
180 laneDetectionsPerCamera,
181 poleDetectionsPerCamera,
182 signAndLightDetectionsPerCamera,
183 &globalEgoResult.position, &globalEgoResult.orientation,
184 &globalEgoUncertainty.position.covariance, &globalEgoUncertainty.orientation.covariance,
190 If a new map needs to be set, the setMap function can be invoked. This function assumes all road segment ID's of the new map match those of the old map.
192 dwLocalization_setMap(newMap, m_localizer);
194 @note The setMap function does not delete the old map. To avoid memory leaks, users should delete the old map if they do not plan to use it again.
199 Upon termination, all allocated resources must be freed:
202 dwRig_release(&m_rigConfig);
203 dwMaps_release(&m_map);
204 dwLocalization_release(&m_localizer);
205 dwLandmarkDetector_release(&m_landmarkDetector);
206 dwEgomotion_release(&m_egomotion)
207 dwGlobalEgomotion_release(&m_globalEgomotion)
211 This workflow is demonstrated in the following sample: @ref dwx_maps_localization_sample