Play Record GPS log¶
Setup¶
Prerequisites¶
Setting your API key token¶
To set your API key token, define it like this:
#define API_TOKEN "YOUR_API_KEY_TOKEN"
replacing YOUR_API_KEY_TOKEN
with your actual API key token text, within the quotes.
This can be done in the main()
function, before the following line:
#if defined(API_TOKEN)
or outside the main()
function, further up, or in a header file.
Although it is also possible to define your API key token as the text value of the GEM_TOKEN
environment variable, this is not recommended, as it is not secure.
Build and run¶
.nmea
file should be copied from the directory of this example
to the Data/Res/
directory within the SDK install path.C:\MAGICLANE\Data\Res\
C:\MAGICLANE\
is the SDK install path.GPSLogs/
directory should also be created within the SDK install path.C:\MAGICLANE\GPSLogs\
In Visual Studio, right-click on the PlayRecordGPSLog
project, and select
Set as Startup Project
then press F5
to run.
How it works¶
1int main( int argc, char** argv )
2{
3 std::string projectApiToken = "";
4#define API_TOKEN "YOUR_API_KEY_TOKEN"
5#if defined(API_TOKEN)
6 projectApiToken = std::string( API_TOKEN );
7#endif
8 // Sdk objects can be created & used below this line
9 Environment::SdkSession session(projectApiToken, { argc > 1 ? argv[1] : "" });
10
11 // Create an interactive map view
12 CTouchEventListener pTouchEventListener;
13 gem::StrongPointer<gem::MapView> mapView = gem::MapView::produce(session.produceOpenGLContext(
14 Environment::WindowFrameworks::ImGUI, "PlayRecordGPSLog", &pTouchEventListener, getUiRender()));
15 if ( !mapView )
16 {
17 GEM_LOGE( "Error creating gem::MapView: %d", GEM_GET_API_ERROR() );
18 }
19 WAIT_UNTIL_WINDOW_CLOSE();
20 return 0;
21}
First, the API key token is set.
Environment::SdkSession session(projectApiToken, { argc > 1 ? argv[1] : "" });
CTouchEventListener pTouchEventListener;
MapView
interactive map instance is created, using an OpenGL context for rendering,
and selecting ImGui for the graphic control interface.gem::StrongPointer<gem::MapView> mapView = gem::MapView::produce(session.produceOpenGLContext(Environment::WindowFrameworks::ImGUI,
"PlayRecordGPSLog", &pTouchEventListener, getUiRender()));
Finally, the getUiRender()
function is passed in, which uses ImGui to render GUI elements,
capture user control input, and call the appropriate SDK functions.
1auto getUiRender()
2{
3 std::string sdkResrcPath = Environment::GetInstance().GetResourcesPath();
4 std::string projectRelativePath = "/Data/Res/";
5 std::string projectAbsolutePath = sdkResrcPath + projectRelativePath;
6 std::string inputGPSlogFile = projectAbsolutePath + "strasbourg.nmea";
7 gem::String logsdir(sdkResrcPath + "GPSLogs");
8 std::pair<gem::sense::DataSourcePtr, int> dataSource = gem::sense::produceLogDataSource(inputGPSlogFile.c_str());
9
10 return std::bind([dataSource, logsdir](gem::StrongPointer<gem::MapView> mapView)
11 {
12 static gem::StrongPointer<gem::Recorder> rec = nullptr;
13 ImGuiIO& io = ImGui::GetIO();
14 const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
15 ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 0, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver);
16 ImGui::Begin("panel", nullptr, ImGuiWindowFlags_NoMove
17 | ImGuiWindowFlags_NoDecoration
18 | ImGuiWindowFlags_AlwaysAutoResize
19 | ImGuiWindowFlags_NoSavedSettings);
20 if (ImGui::Button("Click to play back a pre-recorded route"))
21 {
22 if (dataSource.first)
23 {
24 gem::PositionService().setDataSource(dataSource.first);
25 gem::sense::DataTypeList datatypes;
26 datatypes.push_back(gem::sense::EDataType::Position);
27 datatypes.push_back(gem::sense::EDataType::ImprovedPosition);
28
29 gem::RecorderConfigurationPtr recsrcconfig = gem::StrongPointerFactory<gem::RecorderConfiguration>();
30 recsrcconfig->logsDir = logsdir;
31 recsrcconfig->dataSource = dataSource.first;
32 recsrcconfig->recordedTypes = datatypes;
33 recsrcconfig->chunkDurationSeconds = 60;
34 recsrcconfig->bContinuousRecording = true;
35 recsrcconfig->deleteOlderThanKeepMin = false;
36 recsrcconfig->keepMinSeconds = 3600;
37 rec = gem::Recorder::produce(recsrcconfig);
38 }
39 }
40 if (!mapView->isFollowingPosition())
41 {
42 if (ImGui::Button("Follow position"))
43 {
44 mapView->startFollowingPosition();
45 }
46 }
47 else
48 {
49 ImGui::Text("Following position!");
50 }
51 if (rec)
52 {
53 auto recstat = rec.get()->getStatus();
54 char* str = "UNDEFINED";
55 switch (recstat)
56 {
57 case gem::ERecorderStatus::Restarting: str = "gem::ERecorderStatus::Restarting"; break;
58 case gem::ERecorderStatus::Starting: str = "gem::ERecorderStatus::Starting"; break;
59 case gem::ERecorderStatus::Recording: str = "gem::ERecorderStatus::Recording"; break;
60 case gem::ERecorderStatus::Stopped: str = "gem::ERecorderStatus::Stopped"; break;
61 case gem::ERecorderStatus::Stopping: str = "gem::ERecorderStatus::Stopping"; break;
62 }
63 GEM_LOGE("GPS LOG RECORDER STATUS %s ( %d )", str, recstat);
64 ImGui::Text("GPS LOG RECORDER STATUS %s ( %d )", str, recstat);
65 }
66 if (rec && gem::ERecorderStatus::Stopped == rec.get()->getStatus())
67 {
68 if (ImGui::Button("Start recording GPS log"))
69 {
70 gem::PositionService().setDataSource(dataSource.first);
71 rec.get()->startRecording();
72 }
73 }
74 else if (rec && gem::ERecorderStatus::Recording == rec.get()->getStatus())
75 {
76 if (ImGui::Button("Stop recording GPS log"))
77 {
78 // The GPS log (recording of the playback) is written when the window is closed
79 rec.get()->stopRecording();
80 }
81 }
82 ImGui::End();
83 }
84 , std::placeholders::_1);
85}
Outside the lambda function, the paths and the GPS navigation position log input file name is defined. Inside the lambda function:
First, the main ImGui viewport is obtained, and the x,y position of the ImGui window, with the identifier “panel”, in pixels, is set within the SDK OpenGL viewport.
ImGui::Begin()
function.Playback¶
ImGui::Button()
which the user can click to start playback of an .nmea
GPS position log.gem::PositionService().setDataSource(dataSource.first);
std::pair<gem::sense::DataSourcePtr, int> dataSource = gem::sense::produceLogDataSource(inputGPSlogFile.c_str());
Follow position¶
mapView->startFollowingPosition();
ImGui::Text("Following position!");
element
is displayed instead of the button, to indicate this mode.Record GPS log¶
if (rec && gem::ERecorderStatus::Recording == rec.get()->getStatus())
rec.get()->startRecording();
rec.get()->stopRecording();