How to record thermal data using Olympe

How can I use calls in Olympe to record thermal data - and visible data at the same time - on the SD card?

This follows on from my topic Stream infrared and full-colour video simultaneously. To summarise that: I had hoped to programmatically open both streams in real time (e.g. as two RTSP streams) for processing but it turns out Anafis don’t support this. However, when saving the video to an SD card both streams are present, so I can at least do offline analysis afterwards.

I have tried this out from the Free Flight app and it works fine - I can look at the video on the SD card afterwards and see both the thermal channel and the visible channel. Thanks! But it’s not possible to open the Free Flight app while the Anafi is being controlled by the Olympe (as I was told in my other topic
Connect over API while also using ground control software
), so of course I must start the recording using the Olympe API.

However, while I have managed to record to the SD card with the start_recording command message in Olympe, I cannot figure out how to make it include the thermal stream. I have tried various values thermal.mode enum with the thermal.set_mode command message with no luck:

  • Not setting it at all (presumably the same as setting it to disabled) just records the visible stream.
  • Setting it to standard (which by the sounds of its description is the right choice) causes start_recording to return an error and nothing is recorded at all.
  • Setting it to blended results in just the visible stream being recorded.

Here is the error trace with standard:

2020-12-03 18:49:07,949 [INFO] 	olympe.drone.AnafiThermal-I001234 - _send_command_impl - thermal.set_mode(<mode.standard: 1>,) has been sent to the device
2020-12-03 18:49:07,949 INFO olympe.drone.AnafiThermal-I001234: thermal.set_mode(<mode.standard: 1>,) has been sent to the device
2020-12-03 18:49:07,958 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - thermal.mode(mode=mode.standard)
2020-12-03 18:49:07,958 INFO olympe.drone.AnafiThermal-I001234: thermal.mode(mode=mode.standard)
2020-12-03 18:49:07,962 [INFO] 	olympe.drone.AnafiThermal-I001234 - _send_command_impl - camera.start_recording(0,) has been sent to the device
2020-12-03 18:49:07,962 INFO olympe.drone.AnafiThermal-I001234: camera.start_recording(0,) has been sent to the device
2020-12-03 18:49:07,964 [INFO] 	olympe.drone.AnafiThermal-I001234 - _send_command_impl - camera.start_recording(0,) has been sent to the device
2020-12-03 18:49:07,964 INFO olympe.drone.AnafiThermal-I001234: camera.start_recording(0,) has been sent to the device
2020-12-03 18:49:08,108 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_progress(cam_id=0, result=recording_result.error_bad_state, media_id='', list_flags='')
2020-12-03 18:49:08,108 INFO olympe.drone.AnafiThermal-I001234: camera.recording_progress(cam_id=0, result=recording_result.error_bad_state, media_id='', list_flags='')
2020-12-03 18:49:08,258 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_state(cam_id=0, available=availability.not_available, state=state.inactive, start_timestamp=0, list_flags='')
2020-12-03 18:49:08,258 INFO olympe.drone.AnafiThermal-I001234: camera.recording_state(cam_id=0, available=availability.not_available, state=state.inactive, start_timestamp=0, list_flags='')
2020-12-03 18:49:08,260 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.stopped, error=VideoStateChangedV2_Error.ok)
2020-12-03 18:49:08,260 INFO olympe.drone.AnafiThermal-I001234: ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.stopped, error=VideoStateChangedV2_Error.ok)
2020-12-03 18:49:08,261 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_progress(cam_id=0, result=recording_result.error_bad_state, media_id='', list_flags='')
2020-12-03 18:49:08,261 INFO olympe.drone.AnafiThermal-I001234: camera.recording_progress(cam_id=0, result=recording_result.error_bad_state, media_id='', list_flags='')
2020-12-03 18:49:08,262 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_state(cam_id=0, available=availability.not_available, state=state.inactive, start_timestamp=0, list_flags='')
2020-12-03 18:49:08,262 INFO olympe.drone.AnafiThermal-I001234: camera.recording_state(cam_id=0, available=availability.not_available, state=state.inactive, start_timestamp=0, list_flags='')
2020-12-03 18:49:08,263 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.stopped, error=VideoStateChangedV2_Error.ok)
2020-12-03 18:49:08,263 INFO olympe.drone.AnafiThermal-I001234: ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.stopped, error=VideoStateChangedV2_Error.ok)

Here is the trace when using blended mode:

2020-12-03 19:22:39,577 [INFO] 	olympe.drone.AnafiThermal-I001234 - _send_command_impl - thermal.set_mode(<mode.blended: 2>,) has been sent to the device
2020-12-03 19:22:39,577 INFO olympe.drone.AnafiThermal-I001234: thermal.set_mode(<mode.blended: 2>,) has been sent to the device
2020-12-03 19:22:39,589 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - thermal.mode(mode=mode.disabled)
2020-12-03 19:22:39,589 INFO olympe.drone.AnafiThermal-I001234: thermal.mode(mode=mode.disabled)
2020-12-03 19:22:49,589 [INFO] 	olympe.drone.AnafiThermal-I001234 - _send_command_impl - camera.start_recording(0,) has been sent to the device
2020-12-03 19:22:49,589 INFO olympe.drone.AnafiThermal-I001234: camera.start_recording(0,) has been sent to the device
2020-12-03 19:22:49,656 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_progress(cam_id=0, result=recording_result.started, media_id='', list_flags='')
2020-12-03 19:22:49,656 INFO olympe.drone.AnafiThermal-I001234: camera.recording_progress(cam_id=0, result=recording_result.started, media_id='', list_flags='')
2020-12-03 19:22:49,806 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - camera.recording_state(cam_id=0, available=availability.available, state=state.active, start_timestamp=1607023369460, list_flags='')
2020-12-03 19:22:49,806 INFO olympe.drone.AnafiThermal-I001234: camera.recording_state(cam_id=0, available=availability.available, state=state.active, start_timestamp=1607023369460, list_flags='')
2020-12-03 19:22:49,807 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.started, error=VideoStateChangedV2_Error.ok)
2020-12-03 19:22:49,807 INFO olympe.drone.AnafiThermal-I001234: ardrone3.MediaRecordState.VideoStateChangedV2(state=VideoStateChangedV2_State.started, error=VideoStateChangedV2_Error.ok)
2020-12-03 19:22:49,808 [INFO] 	olympe.drone.AnafiThermal-I001234 - _recv_cmd_cb - common.RunState.RunIdChanged(runId='017EBF')
2020-12-03 19:22:49,808 INFO olympe.drone.AnafiThermal-I001234: common.RunState.RunIdChanged(runId='017EBF')

What is the correct procedure to record both streams to the SD card using commands in Olympe?