Generating a Scanning Sequence File with Python

Speos provides you with an Python script file to help you understand how to create and generate the *.OPTScanSequence / *.txt file to be used in the LiDAR Speos definition.

To generate the *.OPTScanSequence / *.txt:

Prerequisites: Make sure your regional settings use a "." as decimal separator and not a ",".
Prerequisites: Download the speos_Firing_Sequence_File_Examples.zip file.
  1. Open the LiDAR_scanning_sequence_generator.py python script file.
    Note: From the Line 156, you will define the parameters to set as indicated by the comments. However the line numbering can vary according to the modifications you apply.
  2. From Line 162, define the PulseShape (Rectangular, Triangular, Gaussian, Dirac) and PulseWidth corresponding to the default width of pulses in seconds.
    #setup default pulse shape
    scan_sequence_data_model.EPulseShape = OptisCore.Enum_PulseShape(OptisCore.PulseShapeGaussian)
    scan_sequence_data_model.PulseWidth = 0.001
  3. From Line 166, if you want to apply an unique wavelength, define the default monochromatic spectrum in nm.
    # add a monochromatic spectrum
    spectrum_Monochromatic = OptisCore.DSpectrumMonochromatic.Make()
    spectrum_Monochromatic.Ptr().Wavelength = 950.0
    scan_sequence_data_model.SpectrumList.Push_back(OptisCore.SharedPtr_Cast_DISpectrum_From_DSpectrumMonochromatic(spectrum_Monochromatic))
  4. From Line 171, ff you want to apply a spectrum with multiple wavelengths, define the sampled spectrum in nm.
    # add a sampled spectrum
    spectrum_Sampled = OptisCore.DSpectrumSampled.Make()
    
    # Define the number of wavelength of the spectrum
    numberOfWavelengths = 11
    spectrum_Sampled.Ptr().Wavelengths.Resize(numberOfWavelengths)
    spectrum_Sampled.Ptr().Values.Resize(numberOfWavelengths)
    
    # Define the value of each wavelength
    for i in range(numberOfWavelengths):
    w = 945.0 + i * 10.0 / (numberOfWavelengths - 1)
    spectrum_Sampled.Ptr().Wavelengths.Set(i, w)
    spectrum_Sampled.Ptr().Values.Set(i, 25.0 - (w - 950.0) ** 2)
    		
    scan_sequence_data_model.SpectrumList.Push_back(OptisCore.SharedPtr_Cast_DISpectrum_From_DSpectrumSampled(spectrum_Sampled))
  5. From Line 184, define the intensity distribution of the beams.
    # add an intensity distribution
    numberOfPhiAngles = 5
    numberOfThetaAngles = 13
    intensity = OptisCore.DDistribution2Double.Make()
    intensity.Ptr().Distribution.Allocate(numberOfPhiAngles, numberOfThetaAngles)
    
    for p in range(numberOfPhiAngles):
    intensity.Ptr().Distribution.m_X.Set(p, p * 360.0 / (numberOfPhiAngles - 1))
    
    pos = OptisCore.Extent_uint_2()
    
    for t in range(numberOfThetaAngles):
    theta = 90.0 * t / (numberOfThetaAngles - 1)
    intensity.Ptr().Distribution.m_Y.Set(t, theta)
    pos.Set(1, t)
    
    for p in range(numberOfPhiAngles):
    pos.Set(0, p)
    intensity.Ptr().Distribution.m_Value.Set(pos, math.cos(math.radians(theta))) # lambertian (no need to normalize)
    
    scan_sequence_data_model.SampledIntensityList.Push_back(intensity)
  6. From Line 206, add as many beams as you want:
    # add few beams:
    scanParameters1 = OptisCore.DScanParam()
    scanParameters1.Position.Init(0.1, 0.2, 0.3) # mm
    
    # Choose between Rectangular and Elliptic
    # Or for a Point shape, do not add the parameters ESurfaceShape, SizeX, SizeY
    scanParameters1.ESurfaceShape = OptisCore.Enum_LidarEmissionSurfaceShape(OptisCore.LidarEmissionSurfaceShapeRectangular)
    scanParameters1.SizeX = 3.0 # mm
    scanParameters1.SizeY = 2.0 # mm
    
    scanParameters1.ShootingTime = 0.001 # s
    
    scanParameters1.PulseEnergy = 0.05 # J
    
    # Choose between Triangular, Rectangular, Gaussian, Dirac
    # Or use ShapeUndefined to use the PulseShape defined in Step 3
    scanParameters1.EPulseShape = OptisCore.Enum_PulseShape(OptisCore.PulseShapeTriangular)
    
    # If you want to use the PulseWidth defined in Step 3, do not add the parameter line for PulseWidth 
    scanParameters1.PulseWidth = 0.00002 # s
    
    # If you do not want to apply an angle, do not add the corresponding parameter line
    scanParameters1.RotationAngle = 0.0132 # azimuth angle in degrees
    scanParameters1.TiltAngle = 0.0276 # elevation angle degrees
    scanParameters1.PsiAngle = 0.234 # degrees
    
    # Choose between Gaussian and Sampled
    # Or reomove the parameter line to use the Intensity defined in the Source - Intensity section's parameters from the LiDAR sensor definition
    scanParameters1.EIntensityType = OptisCore.Enum_LidarIntensityType(OptisCore.LidarIntensityTypeSampled)
    
    # If you selected Sampled as EIntensityType, add the following parameter line IntensityIndex and define its index
    scanParameters1.IntensityIndex = 0
    
    #If you selected Gaussian as EIntensityType, add the following parameter lines
    scanParameters1.GaussianXWidth = 0.5 # FWHM in degrees
    scanParameters1.GaussianYHeight = 0.5 # FWHM in degrees
    scanParameters1.GaussianTotalAngle = 10.0 # degrees
    
    scanParameters1.SpectrumIndex = 1
    
    scan_sequence_data_model.ScanParamList.Push_back(scanParameters1)

    For each beam you add, define its parameters using the following template:

    scanParametersN = OptisCore.DScanParam()
    scanParametersN.PARAMETER_TO_DEFINE
    scanParametersN.PARAMETER_TO_DEFINE
    ...
    ...
    scan_sequence_data_model.ScanParamList.Push_back(scanParametersN)
  7. From Line 249, define the *OPTScanSequence file name.
    # serialization file
    currentdirectory = os.path.dirname(os.path.realpath(__file__))
    sequence_file_name = OptisCore.String(os.path.join(currentdirectory, "sampleFile.OPTScanSequence"))
    sequence_filepath = OptisCore.Path(sequence_file_name)
  8. Close the Python script file and run it.
A *.OPTScanSequence file has been generated and is ready to be used in a LiDAR sensor definition.