DriveWorks SDK Reference
3.5.78 Release
For Test and Development only

localization/docs/usecase1.md
Go to the documentation of this file.
1 # Copyright (c) 2019-2020 NVIDIA CORPORATION. All rights reserved.
2 
3 @page localization_usecase1 Camera Localization
4 @note SW Release Applicability: This tutorial is applicable to modules in **NVIDIA DRIVE Software** releases.
5 
6 ## Workflow
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.
18 
19 Below is the general structure for usage, for the full implementation refer to @ref dwx_maps_localization_sample.
20 
21 ## Initialization
22 
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.
26 
27 The following snippet initializes the @ref maps_mainsection.
28 
29 ```{.cpp}
30  dwMaps_initialize(&m_map, mapFilePath, m_context);
31 ```
32 
33 The snippet below initializes the @ref rig_mainsection module.
34 
35 ```{.cpp}
36  dwRig_initializeFromFile(&m_rigConfig, m_context, rigFile);
37 ```
38 
39 The next snippet initializes the @ref landmarks_mainsection module.
40 ```{.cpp}
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);
48 ```
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.
52 
53 The snippet below initializes the @ref egomotion_mainsection module with example parameters. Both the relative and global (GNSS dependent)
54 variants are required.
55 
56 ```{.cpp}
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;
63 
64  dwEgomotion_initialize(&m_egomotion, &relativeEgomotionParams, m_context);
65 
66  // global egomotion parameters
67  dwGlobalEgomotionParameters globalEgomotionParams = {};
68  dwGlobalEgomotion_initParamsFromRig(&globalEgomotionParams, m_rigConfig, m_gpsSensorName);
69 
70  dwGlobalEgomotion_initialize(&m_globalEgomotion, &globalEgomotionParams, m_context);
71 ```
72 
73 Once all dependencies are set up, the @ref localization_mainsection module can be initialized.
74 
75 ```{.cpp}
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);
80 ```
81 
82 Once the @ref localization_mainsection module is initialized, the HD map can be changed.
83 ```{.cpp}
84  dwLocalization_setMap(m_map, m_localizer);
85 ```
86 
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.
93 
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.
96 
97 ```{.cpp}
98 dwLaneDetection lanes{};
99 dwLandmarkDetection poles{};
100 dwRoadmarkDetection roadmarks{};
101 dwLandmarkDetector_detectLandmarks(&lanes, &poles, &roadmarks, cameraFrame, m_landmarkDetector)
102 ```
103 
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.
108 
109 ```{.cpp}
110  // CAN and IMU data required for relative egomotion
111 
112  if (hasCANMessage())
113  {
114  ... // Parse the CAN message and get vehicle state
115 
116  dwEgomotion_addVehicleState(&currVehicleState, m_egomotion)
117  }
118 
119  if (hasIMUMeasurement())
120  {
121  dwEgomotion_addIMUMeasurement(&imuFrame, m_egomotion);
122  }
123 
124  // GPS data and relative egomotion required for global egomotion
125 
126  if (hasGPSMeasurement())
127  {
128  dwGlobalEgomotion_addGPSMeasurement(&gpsFrame, m_globalEgomotion);
129  }
130 
131  {
132  // Update global egomotion module with latest relative egomotion state
133  dwEgomotionResult state = {};
134  dwEgomotionUncertainty uncertainty = {};
135 
136  if (dwEgomotion_getEstimation(&state, m_egomotion) == DW_SUCCESS &&
137  dwEgomotion_getUncertainty(&uncertainty, m_egomotion) == DW_SUCCESS)
138  {
139  dwGlobalEgomotion_addRelativeMotion(&state, &uncertainty, m_globalEgomotion);
140  }
141  }
142 
143 ```
144 
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.
150 
151 The snippet below highlights the steps necessary for obtaining correct measurements from the @ref egomotion_mainsection modules:
152 
153 ```{.cpp}
154  // Obtain relative transform from egomotion
155  dwTransformation3f currToPrev = {};
156  dwStatus relativeEgoStatus = dwEgomotion_computeRelativeTransformation(&currToPrev, nullptr,
157  cameraTimestamp, m_prevCameraTimestamp,
158  m_egomotion);
159 
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;
167 ```
168 
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.
172 
173 ## Localization
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.
176 
177 ```{.cpp}
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,
185  &currToPrev,
186  cameraTimestamp,
187  m_localizer);
188 ```
189 
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.
191 ```{.cpp}
192  dwLocalization_setMap(newMap, m_localizer);
193 ```
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.
195 
196 
197 ## Termination
198 
199 Upon termination, all allocated resources must be freed:
200 
201 ```
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)
208 ```
209 
210 
211 This workflow is demonstrated in the following sample: @ref dwx_maps_localization_sample