Skip to content

Commit 10775d2

Browse files
abastieadujardin
authored andcommitted
Adding new features from SDK 2.4 to 2.7 (#58)
* InputType class * Plane class and plane detection functions * camera_imu_transform in CameraInformation * getRecommendedRange in spatialMappingParameters * coordinate system RIGHT_HANDED_Z_UP_X_FWD * optional_settings_path in initParameters * pose_covariance in Pose * SVO H264 / H265 * enable_imu_fusion * Plane detection sample
1 parent 5bfc7bc commit 10775d2

File tree

11 files changed

+426
-8
lines changed

11 files changed

+426
-8
lines changed

examples/plane_example.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
########################################################################
2+
#
3+
# Copyright (c) 2018, STEREOLABS.
4+
#
5+
# All rights reserved.
6+
#
7+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
8+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
10+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
11+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
12+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
13+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
14+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
15+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
17+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18+
#
19+
########################################################################
20+
21+
"""
22+
Plane sample that save the floor plane detected as a mesh.
23+
"""
24+
import sys
25+
import pyzed.camera as zcam
26+
import pyzed.core as core
27+
import pyzed.mesh as mesh
28+
import pyzed.types as tp
29+
30+
31+
def main():
32+
cam = zcam.PyZEDCamera()
33+
init = zcam.PyInitParameters()
34+
35+
if len(sys.argv) == 2:
36+
filepath = sys.argv[1]
37+
print("Reading SVO file: {0}".format(filepath))
38+
init.set_from_svo_file(filepath)
39+
40+
status = cam.open(init)
41+
if status != tp.PyERROR_CODE.PySUCCESS:
42+
print(repr(status))
43+
exit(1)
44+
45+
runtime = zcam.PyRuntimeParameters()
46+
spatial = zcam.PySpatialMappingParameters()
47+
48+
transform = core.PyTransform()
49+
tracking = zcam.PyTrackingParameters(transform)
50+
51+
cam.enable_tracking(tracking)
52+
cam.enable_spatial_mapping(spatial)
53+
54+
pymesh = mesh.PyMesh()
55+
pyplane = mesh.PyPlane()
56+
reset_tracking_floor_frame = core.PyTransform()
57+
found = 0
58+
print("Processing...")
59+
for i in range(1000):
60+
cam.grab(runtime)
61+
err = cam.find_floor_plane(pyplane, reset_tracking_floor_frame)
62+
if i > 200 and err == tp.PyERROR_CODE.PySUCCESS:
63+
found = 1
64+
print('Floor found!')
65+
pymesh = pyplane.extract_mesh()
66+
break
67+
68+
if found == 0:
69+
print('Floor was not found, please try with another SVO.')
70+
cam.close()
71+
exit(0)
72+
73+
cam.disable_tracking()
74+
cam.disable_spatial_mapping()
75+
76+
save_mesh(pymesh)
77+
cam.close()
78+
print("\nFINISH")
79+
80+
81+
def save_mesh(pymesh):
82+
while True:
83+
res = input("Do you want to save the mesh? [y/n]: ")
84+
if res == "y":
85+
msh = tp.PyERROR_CODE.PyERROR_CODE_FAILURE
86+
while msh != tp.PyERROR_CODE.PySUCCESS:
87+
filepath = input("Enter filepath name: ")
88+
msh = pymesh.save(filepath)
89+
print("Saving mesh: {0}".format(repr(msh)))
90+
if msh:
91+
break
92+
else:
93+
print("Help : you must enter the filepath + filename without extension.")
94+
break
95+
elif res == "n":
96+
print("Mesh will not be saved.")
97+
break
98+
else:
99+
print("Error, please enter [y/n].")
100+
101+
if __name__ == "__main__":
102+
main()

pyzed/camera.pxd

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ cimport pyzed.core as core
2929
cimport pyzed.types as types
3030
cimport pyzed.mesh as mesh
3131

32+
cdef extern from 'cuda.h' :
33+
cdef struct CUctx_st :
34+
pass
35+
ctypedef CUctx_st* CUcontext
3236

3337
cdef extern from 'sl/Camera.hpp' namespace 'sl':
3438

@@ -43,6 +47,13 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
4347
MAPPING_RANGE_MEDIUM 'sl::SpatialMappingParameters::MAPPING_RANGE::MAPPING_RANGE_MEDIUM'
4448
MAPPING_RANGE_FAR 'sl::SpatialMappingParameters::MAPPING_RANGE::MAPPING_RANGE_FAR'
4549

50+
cdef cppclass InputType 'sl::InputType':
51+
InputType()
52+
InputType(InputType &type)
53+
54+
void setFromCameraID(unsigned int id)
55+
void setFromSerialNumber(unsigned int serial_number)
56+
void setFromSVOFile(types.String svo_input_filename)
4657

4758
cdef cppclass InitParameters 'sl::InitParameters':
4859
defines.RESOLUTION camera_resolution
@@ -64,6 +75,10 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
6475

6576
types.String sdk_verbose_log_file
6677

78+
CUcontext sdk_cuda_ctx
79+
InputType input
80+
types.String optional_settings_path
81+
6782
InitParameters(defines.RESOLUTION camera_resolution,
6883
int camera_fps,
6984
int camera_linux_id,
@@ -80,7 +95,10 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
8095
bool enable_right_side_measure,
8196
int camera_buffer_count_linux,
8297
types.String sdk_verbose_log_file,
83-
bool depth_stabilization)
98+
bool depth_stabilization,
99+
CUcontext sdk_cuda_ctx,
100+
InputType input,
101+
types.String optional_settings_path)
84102

85103
bool save(types.String filename)
86104
bool load(types.String filename)
@@ -104,7 +122,10 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
104122
cdef cppclass TrackingParameters 'sl::TrackingParameters':
105123
core.Transform initial_world_transform
106124
bool enable_spatial_memory
125+
bool enable_pose_smoothing
126+
bool set_floor_as_origin
107127
types.String area_file_path
128+
bool enable_imu_fusion
108129

109130
TrackingParameters(core.Transform init_pos,
110131
bool _enable_memory,
@@ -113,7 +134,6 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
113134
bool save(types.String filename)
114135
bool load(types.String filename)
115136

116-
117137
cdef cppclass SpatialMappingParameters 'sl::SpatialMappingParameters':
118138
ctypedef pair[float, float] interval
119139

@@ -132,6 +152,12 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
132152
@staticmethod
133153
float get(MAPPING_RANGE range)
134154

155+
@staticmethod
156+
float getRecommendedRange(MAPPING_RESOLUTION mapping_resolution, Camera &camera)
157+
158+
@staticmethod
159+
float getRecommendedRange(float resolution_meters, Camera &camera)
160+
135161
void set(MAPPING_RANGE range)
136162

137163
int max_memory_usage
@@ -164,7 +190,7 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
164190
core.Transform pose_data
165191

166192
int pose_confidence
167-
193+
float pose_covariance[36]
168194

169195
cdef cppclass IMUData(Pose):
170196
IMUData()
@@ -227,6 +253,9 @@ cdef extern from 'sl/Camera.hpp' namespace 'sl':
227253
types.ERROR_CODE retrieveMeshAsync(mesh.Mesh &mesh)
228254
void disableSpatialMapping()
229255

256+
types.ERROR_CODE findPlaneAtHit(types.Vector2[uint] coord, mesh.Plane &plane)
257+
types.ERROR_CODE findFloorPlane(mesh.Plane &plane, core.Transform &resetTrackingFloorFrame, float floor_height_prior, core.Rotation world_orientation_prior, float floor_height_prior_tolerance)
258+
230259
types.ERROR_CODE enableRecording(types.String video_filename, defines.SVO_COMPRESSION_MODE compression_mode)
231260
defines.RecordingState record()
232261
void disableRecording()
@@ -253,6 +282,8 @@ cdef extern from "Utils.cpp" namespace "sl":
253282
bool saveMatPointCloudAs(core.Mat &cloud, defines.POINT_CLOUD_FORMAT format, types.String name,
254283
bool with_color)
255284

285+
cdef class PyInputType:
286+
cdef InputType input
256287

257288
cdef class PyZEDCamera:
258289
cdef Camera camera

pyzed/camera.pyx

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,26 @@ class PyRANGE(enum.Enum):
4444
PyRANGE_MEDIUM = MAPPING_RANGE_MEDIUM
4545
PyRANGE_FAR = MAPPING_RANGE_FAR
4646

47+
cdef class PyInputType:
48+
def __cinit__(self, input_type=0):
49+
if input_type == 0 :
50+
self.input = InputType()
51+
elif isinstance(input_type, PyInputType) :
52+
input_t = <PyInputType> input_type
53+
self.input = InputType(input_t.input)
54+
else :
55+
raise TypeError("Argument is not of right type.")
56+
57+
def set_from_camera_id(self, id):
58+
self.input.setFromCameraID(id)
59+
60+
def set_from_serial_number(self, serial_number):
61+
self.input.setFromSerialNumber(serial_number)
62+
63+
def set_from_svo_file(self, str svo_input_filename):
64+
filename = svo_input_filename.encode()
65+
self.input.setFromSVOFile(types.String(<char*> filename))
66+
4767

4868
cdef class PyInitParameters:
4969
cdef InitParameters* init
@@ -54,7 +74,8 @@ cdef class PyInitParameters:
5474
coordinate_system=defines.PyCOORDINATE_SYSTEM.PyCOORDINATE_SYSTEM_IMAGE,
5575
sdk_verbose=False, sdk_gpu_id=-1, depth_minimum_distance=-1.0, camera_disable_self_calib=False,
5676
camera_image_flip=False, enable_right_side_measure=False, camera_buffer_count_linux=4,
57-
sdk_verbose_log_file="", depth_stabilization=True):
77+
sdk_verbose_log_file="", depth_stabilization=True, PyInputType input_t=PyInputType(),
78+
optional_settings_path=""):
5879
if (isinstance(camera_resolution, defines.PyRESOLUTION) and isinstance(camera_fps, int) and
5980
isinstance(camera_linux_id, int) and isinstance(svo_input_filename, str) and
6081
isinstance(svo_real_time_mode, bool) and isinstance(depth_mode, defines.PyDEPTH_MODE) and
@@ -63,16 +84,19 @@ cdef class PyInitParameters:
6384
isinstance(sdk_gpu_id, int) and isinstance(depth_minimum_distance, float) and
6485
isinstance(camera_disable_self_calib, bool) and isinstance(camera_image_flip, bool) and
6586
isinstance(enable_right_side_measure, bool) and isinstance(camera_buffer_count_linux, int) and
66-
isinstance(sdk_verbose_log_file, str) and isinstance(depth_stabilization, bool)):
87+
isinstance(sdk_verbose_log_file, str) and isinstance(depth_stabilization, bool) and
88+
isinstance(input_t, PyInputType) and isinstance(optional_settings_path, str)):
6789

6890
filename = svo_input_filename.encode()
6991
filelog = sdk_verbose_log_file.encode()
92+
fileoption = optional_settings_path.encode()
7093
self.init = new InitParameters(camera_resolution.value, camera_fps, camera_linux_id,
7194
types.String(<char*> filename), svo_real_time_mode, depth_mode.value,
7295
coordinate_units.value, coordinate_system.value, sdk_verbose, sdk_gpu_id,
7396
depth_minimum_distance, camera_disable_self_calib, camera_image_flip,
7497
enable_right_side_measure, camera_buffer_count_linux,
75-
types.String(<char*> filelog), depth_stabilization)
98+
types.String(<char*> filelog), depth_stabilization,
99+
<CUcontext> 0, input_t.input, types.String(<char*> fileoption))
76100
else:
77101
raise TypeError("Argument is not of right type.")
78102

@@ -243,6 +267,38 @@ cdef class PyInitParameters:
243267
def depth_stabilization(self, bool value):
244268
self.init.depth_stabilization = value
245269

270+
@property
271+
def input(self):
272+
input_t = PyInputType()
273+
input_t.input = self.init.input
274+
return input_t
275+
276+
@input.setter
277+
def input(self, PyInputType input_t):
278+
self.init.input = input_t.input
279+
280+
@property
281+
def optional_settings_path(self):
282+
if not self.init.svo_input_filename.empty():
283+
return self.init.optional_settings_path.get().decode()
284+
else:
285+
return ""
286+
287+
@optional_settings_path.setter
288+
def optional_settings_path(self, str value):
289+
value_filename = value.encode()
290+
self.init.optional_settings_path.set(<char*>value_filename)
291+
292+
def set_from_camera_id(self, id):
293+
self.init.input.setFromCameraID(id)
294+
295+
def set_from_serial_number(self, serial_number):
296+
self.init.input.setFromSerialNumber(serial_number)
297+
298+
def set_from_svo_file(self, str svo_input_filename):
299+
filename = svo_input_filename.encode()
300+
self.init.input.setFromSVOFile(types.String(<char*> filename))
301+
246302

247303
cdef class PyRuntimeParameters:
248304
cdef RuntimeParameters* runtime
@@ -334,6 +390,30 @@ cdef class PyTrackingParameters:
334390
def enable_spatial_memory(self, bool value):
335391
self.tracking.enable_spatial_memory = value
336392

393+
@property
394+
def enable_pose_smoothing(self):
395+
return self.tracking.enable_pose_smoothing
396+
397+
@enable_pose_smoothing.setter
398+
def enable_pose_smoothing(self, bool value):
399+
self.tracking.enable_pose_smoothing = value
400+
401+
@property
402+
def set_floor_as_origin(self):
403+
return self.tracking.set_floor_as_origin
404+
405+
@set_floor_as_origin.setter
406+
def set_floor_as_origin(self, bool value):
407+
self.tracking.set_floor_as_origin = value
408+
409+
@property
410+
def enable_imu_fusion(self):
411+
return self.tracking.enable_imu_fusion
412+
413+
@enable_imu_fusion.setter
414+
def enable_imu_fusion(self, bool value):
415+
self.tracking.enable_imu_fusion = value
416+
337417
@property
338418
def area_file_path(self):
339419
if not self.tracking.area_file_path.empty():
@@ -386,6 +466,14 @@ cdef class PySpatialMappingParameters:
386466
else:
387467
raise TypeError("Argument is not of PyRESOLUTION type.")
388468

469+
def get_recommended_range(self, resolution, PyZEDCamera py_cam):
470+
if isinstance(resolution, PyRESOLUTION):
471+
return self.spatial.getRecommendedRange(<MAPPING_RESOLUTION> resolution.value, py_cam.camera)
472+
elif isinstance(resolution, float):
473+
return self.spatial.getRecommendedRange(<float> resolution, py_cam.camera)
474+
else:
475+
raise TypeError("Argument is not of PyRESOLUTION or float type.")
476+
389477
@property
390478
def max_memory_usage(self):
391479
return self.spatial.max_memory_usage
@@ -499,6 +587,12 @@ cdef class PyPose:
499587
def pose_confidence(self):
500588
return self.pose.pose_confidence
501589

590+
@property
591+
def pose_covariance(self):
592+
cdef np.ndarray arr = np.zeros(36)
593+
for i in range(36) :
594+
arr[i] = self.pose.pose_covariance[i]
595+
return arr
502596

503597
cdef class PyIMUData:
504598
cdef IMUData imuData
@@ -743,6 +837,13 @@ cdef class PyZEDCamera:
743837
def retrieve_mesh_async(self, mesh.PyMesh py_mesh):
744838
return types.PyERROR_CODE(self.camera.retrieveMeshAsync(deref(py_mesh.mesh)))
745839

840+
def find_plane_at_hit(self, coord, mesh.PyPlane py_plane):
841+
cdef types.Vector2[uint] vec = types.Vector2[uint](coord[0], coord[1])
842+
return types.PyERROR_CODE(self.camera.findPlaneAtHit(vec, py_plane.plane))
843+
844+
def find_floor_plane(self, mesh.PyPlane py_plane, core.PyTransform resetTrackingFloorFrame, floor_height_prior = float('nan'), core.PyRotation world_orientation_prior = core.PyRotation(types.PyMatrix3f().zeros()), floor_height_prior_tolerance = float('nan')) :
845+
return types.PyERROR_CODE(self.camera.findFloorPlane(py_plane.plane, resetTrackingFloorFrame.transform, floor_height_prior, world_orientation_prior.rotation, floor_height_prior_tolerance))
846+
746847
def disable_spatial_mapping(self):
747848
self.camera.disableSpatialMapping()
748849

pyzed/core.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ cdef extern from "sl/Core.hpp" namespace "sl":
5858
cdef struct CameraInformation:
5959
CalibrationParameters calibration_parameters
6060
CalibrationParameters calibration_parameters_raw
61+
Transform camera_imu_transform
6162
unsigned int serial_number
6263
unsigned int firmware_version
6364
types.MODEL camera_model
@@ -291,3 +292,4 @@ cdef class PyCameraInformation:
291292
cdef unsigned int serial_number
292293
cdef unsigned int firmware_version
293294
cdef types.MODEL camera_model
295+
cdef PyTransform py_camera_imu_transform

0 commit comments

Comments
 (0)