def defineRoadAttribution():
    localRoadAttribution = road_attribution_pb2.RoadAttributionCategory()

    # We need to cover 2 HERE Maplet aspects here:
    # 1. Road Surface Markings
    # 2. Lane Marking Observations

    # for that reason, we only generate the category envelope and the two frames for the 2 topics here
    # and we dig deeper in separate functions.

    localCategoryEnvelope = base_pb2.CategoryEnvelope()
    localRoadAttribution.envelope.CopyFrom(localCategoryEnvelope)

    # now we add the lanes
    numOfLaneBoundaryDefinitionsPerHEREMaplet = config.getConfig_Int(
        "run_config", "numOfLaneMarkingObservations_perHEREMaplet")

    iterator = int(0)
    while iterator < numOfLaneBoundaryDefinitionsPerHEREMaplet:
        localRoadAttribution.lane_boundary.extend(
            [defineAnIndividualLaneBoundary()])
        iterator += 1

    # now we add the road surface markings
    numOfRoadSurfaceMarkings = config.getConfig_Int(
        "run_config", "numOfSurfaceMarkings_perHEREMaplet")

    iterator = int(0)
    while iterator < numOfRoadSurfaceMarkings:
        localRoadAttribution.surface_marking.extend(
            [defineAnIndividualSurfaceMarking()])
        iterator += 1

    return localRoadAttribution
def DefineCompilerVersion():

    localVersion = base_pb2.Version()

    localVersion.major.value = config.getConfig_Int(
        "map_identification", "map_compiler_version_major")
    localVersion.minor.value = config.getConfig_Int(
        "map_identification", "map_compiler_version_minor")
    localVersion.patch.value = config.getConfig_Int(
        "map_identification", "map_compiler_version_patch")

    return localVersion
def DefineSENSORISVersion():
    ############### 1 ###############
    # we locally define our own version message and append it to the SENSORIS message
    # the way, the version message is valid for non-repeated messages
    localVersion = base_pb2.Version()

    localVersion.major.value = config.getConfig_Int("general", "major_version")
    localVersion.minor.value = config.getConfig_Int("general", "minor_version")
    localVersion.patch.value = config.getConfig_Int("general", "patch_version")
    localVersion.name.value = config.getConfig_Str("general", "version_name")

    return localVersion
def DefineSENSORISDataMessage():

    # A SENSORIS DataMessage has some main fields, these are
    # #1 (envelope)
    # #2 (event group)
    # #3 (event relation)
    # #4 (event source)
    # these elements will be generated here
    # please check deeper going python files for deeper insights

    # generating the data message container itself
    localDataMessage = data_pb2.DataMessage()

    # putting the local data message together
    # see, that the envelope is a non-repeated value, whereas the others are repeated messages
    localDataMessage.envelope.CopyFrom(
        define_Envelope.defineSENSORISEnvelope())

    iterator = int(0)
    while iterator < config.getConfig_Int("run_config", "numOfHEREMaplets"):
        localDataMessage.event_group.extend(
            [define_EventGroup.defineSENSORISEventGroup()])
        iterator += 1

    #localDataMessage.event_relation.extend([define_EventRelation.defineSENSORISEventRelation()])
    #localDataMessage.event_source.extend([define_EventSource.defineSENSORISEventSource()])

    return localDataMessage
def defineSENSORISEnvelope():

    # the Envelope consists for three elements
    # #1 (identifiers)
    # #2 (vehicle dimensions)
    # #3 (field resolution override) // not needed for HERE Maplet
    # #4 (map identification)

    # generating a local container for the content
    localEnvelope = data_pb2.DataMessage.Envelope()

    localIdentifyer = base_pb2.MessageEnvelopeIds()
    localIdentifyer.session_id.value = str(uuid.uuid4())
    localIdentifyer.message_id.value = config.getConfig_Int(
        "general_message_config", "message_id")
    localIdentifyer.vehicle_fleet_id.value = str(uuid.uuid4())
    localIdentifyer.vehicle_id.value = str(uuid.uuid4())
    localIdentifyer.driver_id.value = str(uuid.uuid4())

    localIdentifyer.job_request_id.append(str(uuid.uuid4()))
    localIdentifyer.job_submitter_id.value = str(uuid.uuid4())

    localEnvelope.ids.CopyFrom(localIdentifyer)

    localVehicleDimensions = data_pb2.DataMessage.Envelope.VehicleDimensions()
    localVehicleDimensions.length_to_front.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_x_forward")
    localVehicleDimensions.length_to_back.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_x_backward")
    localVehicleDimensions.length_to_left.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_y_left")
    localVehicleDimensions.length_to_right.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_y_right")
    localVehicleDimensions.length_to_top.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_z_up")
    localVehicleDimensions.length_to_ground.value = config.getConfig_Int(
        "vehicle_dimensions", "vehicle_dimension_z_down")
    localEnvelope.vehicle_dimensions.CopyFrom(localVehicleDimensions)

    # this implementation is highly inefficient. I cannot recoomend to use it
    # you can simply avoid this, if you take the resolutions defined in the comments above your attributes
    #localFieldResolutionOverride = data_pb2.DataMessage.Envelope.FieldResolutionOverride()
    #localFieldResolutionOverride.path.value = "nice/path/to/attribute/with/different/scale/factor/than/defined/in/comment"
    #localFieldResolutionOverride.factor.value = 3 #translates into mulitplicator by 10-times-3 = 1,000
    #localEnvelope.field_resolution_override.extend([localFieldResolutionOverride])

    # provinding some information on used map
    localMapIdentification = data_pb2.DataMessage.Envelope.MapIdentification()
    localMapIdentification.map_source_identification.map_source_name.value = config.getConfig_Str(
        "map_identification", "map_source_name")
    localMapIdentification.map_source_identification.map_source_version.CopyFrom(
        define_Version.DefineMapVersion())
    localMapIdentification.map_compiler_identification.map_compiler_name.value = config.getConfig_Str(
        "map_identification", "map_compiler_name")
    localMapIdentification.map_compiler_identification.map_compiler_version.CopyFrom(
        define_Version.DefineCompilerVersion())
    localMapIdentification.map_format = data_pb2.DataMessage.Envelope.MapIdentification.NDS
    localEnvelope.map_identification.CopyFrom(localMapIdentification)

    return localEnvelope
def defineObjectDetectionCategory():

    localObjectDetection = object_detection_pb2.ObjectDetectionCategory()

    numOfPLOs = config.getConfig_Int("run_config", "numOfPLOs_perHEREMaplet")
    numOfConesAndBarrels = config.getConfig_Int(
        "run_config", "numOfConesBarrels_perHEREMaplet")

    iterator = int(0)
    while iterator < numOfPLOs:
        localObjectDetection.static_object_detection.extend(
            [definePoleLikeObjects()])
        iterator += 1

    iterator = int(0)
    while iterator < numOfConesAndBarrels:
        localObjectDetection.static_object_detection.extend(
            [defineConesAndBarrels()])
        iterator += 1

    return localObjectDetection
Example #7
0
def defineIntersectionAttribution():

  localTrafficSignal = intersection_attribution_pb2.IntersectionAttributionCategory()

  # here we define the mandatory event envelope for the localization
  # There is a little bug in the Sensoris spec, as no content is defined in the category envelope
  # but we define it, to comply
  TrafficSignalCategoryEnvelope = base_pb2.CategoryEnvelope()
  localTrafficSignal.envelope.CopyFrom(TrafficSignalCategoryEnvelope)

  NumOfTrafficSignalsInSensorisMessage = config.getConfig_Int("run_config", "numOfTrafficSignals_perHEREMaplet")
  
  iterator = int(0)
  while iterator < NumOfTrafficSignalsInSensorisMessage:
      localTrafficSignal.traffic_light_status.extend([defineTrafficSignal()])
      localTrafficSignal.traffic_light_cofiguration.extend([defineTrafficLightConfiguration()])
      iterator += 1

  return localTrafficSignal
Example #8
0
def defineObjectDetectionCategory():

    localObjectDetection = object_detection_pb2.ObjectDetectionCategory()

    # the object detecion category has 2 main messages

    # main message generation
    localMovingObject = object_detection_pb2.MovableObjectDetection()
    localStaticObject = object_detection_pb2.StaticObjectDetection()

    # a static object comes with the following attributes to be filled by this script: Lets see, what is happening, if 
    # 1 - envelope
    # 2 - type and confidence
    # 4 - position
    # 5 - rotation
    # 6 - size vector
    # 7 - surface type
    # 8 - surface material type
    
    localStaticObject.envelope.CopyFrom(define_EventEnvelope.defineEventEnvelope(config.getConfig_Int("HERE_MAPLET_CONE_BARREL", "construction_zone_marker_id_int")))

    if config.getConfig_Str("HERE_MAPLET_CONE_BARREL", "construction_zone_cone_type_enum") == "CONE":
        localStaticObject.type_and_confidence.type = object_detection_pb2.StaticObjectDetection.TypeAndConfidence.CONE
        pass

    # THIS IS NOT REQUESTED BY HERE MAPLET
    #localStaticObject.type_and_confidence.confidence_percent.value = 67

    localStaticObject.type_and_confidence.color = base_pb2.GCE_RED

    # generation of the necessary elements

    # handover of the necessary elements

    # main message hand over to the local Object detecion
    # please note, that the static and moveable objects are repeated elements
    # this means, you can add as many objects as you need.
    localObjectDetection.static_object_detection.extend([localStaticObject])
    localObjectDetection.movable_object_detection.extend([localMovingObject])

    return localObjectDetection
def defineSignFacesCategory():

    localSignFaces = traffic_regulation_pb2.TrafficRegulationCategory()

    # The HERE Maplet spec says, that you want to collect the following items:
    # (1) Sign ID
    # (2) timestamp
    # (3) Center Point of detected traffic sign
    # (4) covariance matrix for the position reported
    # (5) orientation
    # (6) height, width and shape of the traffic sign

    # (1) will be defined via the event envelope
    # (2) will be defined via the event envelope
    # (3) will be given via the message "sign recognition" in position and accuracy
    # (4) will be given via the message "sign recognition" in position and accuracy
    # (5) will be given via the message "sign recognition" in the "rotation and accuracy"
    # (6) will be given via the message "size and accuracy" ... shape will be an enum in there as well

    # again, we generate these items several times (configurable) and set some meaningful random fake values

    # here we define the mandatory event envelope for the localization
    # There is a little bug in the Sensoris spec, as no content is defined in the category envelope
    # but we define it, to comply
    signfacesCategoryEnvelope = base_pb2.CategoryEnvelope()
    localSignFaces.envelope.CopyFrom(signfacesCategoryEnvelope)

    NumOfTrafficSignsInSensorisMessage = config.getConfig_Int(
        "run_config", "numOfSignFaces_perHEREMaplet")

    iterator = int(0)
    while iterator < NumOfTrafficSignsInSensorisMessage:
        localSignFaces.sign_recognition.extend([defineTrafficSign()])
        iterator += 1

    return localSignFaces
def main():

    # The SENSORIS-Message basically consists of 3 elements
    # #1 version
    # #2 submitter
    # #3 data message
    #
    # These three elements will be generated here
    # Please go deeper into the python files to see, how these elements are internally generated

    # this is the SENSORIS message itself
    mySensorisMessage = data_pb2.DataMessages()

    # Filling #1 (version)
    mySensorisMessage.version.CopyFrom(
        define_Version.DefineSENSORISVersion(
            config.getConfig_Int("general", "major_version"),
            config.getConfig_Int("general", "minor_version"),
            config.getConfig_Int("general", "patch_version")))

    # Filling #2 (submitter)
    mySensorisMessage.submitter.extend([
        define_Submitter.DefineSENSORISSubmitter(
            config.getConfig_Str("submitter", "OEM_brand"),
            config.getConfig_Str("submitter", "OEM_vehicle_type"),
            config.getConfig_Str("submitter", "OEM_ecu_sw_version"),
            config.getConfig_Str("submitter", "OEM_ecu_hw_version"))
    ])

    # Filling #3 (data message)
    # This is the MAJOR part of SENSORIS!
    mySensorisMessage.data_message.extend(
        [define_DataMessage.DefineSENSORISDataMessage()])

    print mySensorisMessage.__unicode__()

    # writes the protobuf stream on a binary file on disk
    with open('generatedSENSORISmessage.bin', 'wb') as f:
        f.write(mySensorisMessage.SerializeToString())

    # display the size of the written file
    statinfo = os.stat('generatedSENSORISmessage.bin')
    print "Size of written SENSORIS protobuf message is " + str(
        statinfo.st_size) + " Bytes"

    # here we check, if we can read the just dumped data
    mySENSORISmessage_rewrite = data_pb2.DataMessages()
    with open('generatedSENSORISmessage.bin', 'rb') as f:
        mySENSORISmessage_rewrite.ParseFromString(f.read())

    # now we take the binary file from the disk an zip it
    output_message_zip = zipfile.ZipFile('generatedSENSORISmessage.zip', 'w')
    output_message_zip.write('generatedSENSORISmessage.bin',
                             compress_type=zipfile.ZIP_DEFLATED)
    output_message_zip.close()

    # display the size of the compressed written file
    statinfo = os.stat('generatedSENSORISmessage.zip')
    print "Size of written SENSORIS protobuf message is " + str(
        statinfo.st_size) + " Bytes (compressed via zip)"

    return
def defineSENSORISEnvelope():

    # the Envelope consists for three elements
    # #1 (identifiers)
    # #2 (adapted factor)
    # #3 (vehicle dimensions)

    # generating a local container for the content
    localEnvelope = data_pb2.DataMessage.Envelope()
    localIdentifyer = base_pb2.MessageEnvelopeIds()
    localVehicleDimensions = spatial_pb2.BoundingBox.Metric()

    # filling the identifiers with life
    localIdentifyer.session_id.value = str(uuid.uuid4())
    # why is the message_id a number, but the rest a string?
    localIdentifyer.message_id.value = config.getConfig_Int(
        "general_message_config", "message_id")

    localIdentifyer.vehicle_fleet_id.value = str(uuid.uuid4())
    localIdentifyer.vehicle_id.value = str(uuid.uuid4())
    localIdentifyer.driver_id.value = str(uuid.uuid4())

    # 2.1 defining the minimum vehicle dimensions
    # this is practially a bounding box around the vehicle
    localminposition = spatial_pb2.Position.Metric()

    # as an example, we take the values of an Audi A8 from year 2017
    # length:   5135mm    (maximum: 5265mm)
    # width:    1945mm     (maximum: 1949mm)
    # height:   1460mm    (maximum: 1473mm)
    localminposition.x_m.value = config.getConfig_Int(
        "vehicle_dimensions", "minimal_vehicle_length_mm")
    localminposition.y_m.value = config.getConfig_Int(
        "vehicle_dimensions", "minimal_vehicle_width_mm")
    localminposition.z_m.value = config.getConfig_Int(
        "vehicle_dimensions", "minimal_vehicle_height_mm")

    # 2.1 defining the minimum vehicle dimensions
    # this is practially a bounding box around the vehicle
    localmaxposition = spatial_pb2.Position.Metric()
    localmaxposition.x_m.value = config.getConfig_Int(
        "vehicle_dimensions", "maximal_vehicle_length_mm")
    localmaxposition.y_m.value = config.getConfig_Int(
        "vehicle_dimensions", "maximal_vehicle_width_mm")
    localmaxposition.z_m.value = config.getConfig_Int(
        "vehicle_dimensions", "maximal_vehicle_height_mm")

    localVehicleDimensions.min_position.CopyFrom(localminposition)
    localVehicleDimensions.max_position.CopyFrom(localmaxposition)

    localMessageFactor = data_pb2.DataMessage.Envelope.Factor()
    # localMessageFactor.field_mask = 1
    localMessageFactor.factor = config.getConfig_Int("general_message_config",
                                                     "scale_factor")

    # scale factor 3 means, that you interpret all values in "meter" as "millimeter"
    # example: vehicle width=2,5135m is represented as width 2513

    # putting it all together
    localEnvelope.adapted_factor.extend([localMessageFactor])
    localEnvelope.ids.CopyFrom(localIdentifyer)
    localEnvelope.vehicle_dimensions.CopyFrom(localVehicleDimensions)

    return localEnvelope