Skip to content

Scenario generator #450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dist/
doc/html
doc/latex
osi/
venv/

# Specific extensions
*.egg-info
Expand Down
164 changes: 164 additions & 0 deletions gen_scenarios/gen_scenario.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from osi3.osi_sensorview_pb2 import SensorView
import struct
import argparse
import os
import random

"""
This program generates currently random scenarios with predefined message count and moving object count.
This scenario generator can also be used to test the performance of osi-visualizer.

Example usage:
python gen_scenario.py --output "movingobject" --message 10 --moving_objects 5 --random
python gen_scenario.py --output "movingobject" --messages 100 --moving_objects 100 --random
"""


def command_line_arguments():
""" Define and handle command line interface """

parser = argparse.ArgumentParser(
description="Generate OSI scenarios.", prog="gen_scenario"
)
parser.add_argument(
"--output",
"-o",
help="Name of the output file.",
default="output.osi",
type=str,
)
parser.add_argument(
"--messages",
"-m",
help="Path to the file with serialized data.",
default=1,
type=int,
)
parser.add_argument(
"--moving_objects",
"-mo",
help="Count of the movin objects.",
default=0,
type=int,
required=False,
)
parser.add_argument(
"--stationary_objects",
"-so",
help="Count of the stationary objects.",
default=0,
type=int,
required=False,
)
parser.add_argument(
"--random",
"-r",
help="Random placement of objects into the world.",
default=True,
required=False,
action="store_true",
)

return parser.parse_args()


def main():
# Handling of command line arguments
args = command_line_arguments()
message_count = args.messages
moving_objects_count = args.moving_objects
use_random = args.random
output = args.output

moving_objects_dict = {}
stationary_objects_dict = {}

"""Initialize SensorView"""
f = open(f"sv_312_320_{moving_objects_count}_{output}.osi", "ab")
sensorview = SensorView()

sv_ground_truth = sensorview.global_ground_truth
sv_ground_truth.version.version_major = 3
sv_ground_truth.version.version_minor = 1
sv_ground_truth.version.version_patch = 2

sv_ground_truth.timestamp.seconds = 0
sv_ground_truth.timestamp.nanos = 0

# Create moving object dictionary
for mo in range(args.moving_objects):
moving_object = sv_ground_truth.moving_object.add()
moving_object.id.value = mo

moving_object.base.position.x = random.randint(0, 100) if use_random else 0.0
moving_object.base.position.y = random.randint(0, 100) if use_random else 0.0
moving_object.base.position.z = random.randint(0, 100) if use_random else 0.0

# Vehicle dimension
moving_object.base.dimension.length = 5
moving_object.base.dimension.width = 2
moving_object.base.dimension.height = 1

# Classification type
moving_object.vehicle_classification.type = 2

# Direction
moving_object.base.orientation.roll = 0.0
moving_object.base.orientation.pitch = 0.0
moving_object.base.orientation.yaw = 0.0

# Save in dictionary
moving_objects_dict[mo] = moving_object

# Create stationary object dictionary
for so in range(args.stationary_objects):
stationary_object = sv_ground_truth.stationary_object.add()
stationary_object.id.value = so

stationary_object.base.position.x = random.randint(0, 10000) if use_random else 0.0
stationary_object.base.position.y = random.randint(0, 100) if use_random else 0.0
stationary_object.base.position.z = random.randint(0, 100) if use_random else 0.0

# Object dimension
stationary_object.base.dimension.length = 5
stationary_object.base.dimension.width = 5
stationary_object.base.dimension.height = 5

# Direction
stationary_object.base.orientation.roll = 0.0
stationary_object.base.orientation.pitch = 0.0
stationary_object.base.orientation.yaw = 0.0

# Save in dictionary
stationary_objects_dict[so] = stationary_object

# Generate OSI messages
nano_increment = 10000000
for message_num in range(args.messages):

# Increment the time by one second
if sv_ground_truth.timestamp.nanos > 1000000000:
sv_ground_truth.timestamp.seconds += 1
sv_ground_truth.timestamp.nanos = 0
sv_ground_truth.timestamp.nanos += nano_increment

for mo_key, mo in moving_objects_dict.items():

mo.base.position.x += 0.5
mo.base.position.y = mo.base.position.y
mo.base.position.z = mo.base.position.z

mo.base.orientation.yaw += 0.1
mo.base.orientation.roll += 0.1
mo.base.orientation.pitch += 0.1

"""Serialize"""
bytes_buffer = sensorview.SerializeToString()
f.write(struct.pack("<L", len(bytes_buffer)))
f.write(bytes_buffer)

f.close()


if __name__ == "__main__":
main()
46 changes: 46 additions & 0 deletions gen_scenarios/performace/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// \file clock.h
// \brief Platform independent time stamp
//
// \author Georg Seifert <Georg.Seifert@carissma.eu>
// \version 0.1
// \date 2021
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, you can obtain one at http://mozilla.org/MPL/2.0/
//

#ifndef HIGH_PRECITION_CLOCK_H
#define HIGH_PRECITION_CLOCK_H

#ifdef __unix__
#include <time.h>
#include <stdint.h>
#elif _WIN32
#include <windows.h>
#include <stdint.h>
#else
#error "OS not supported!"
#endif

// \brief Time stamp with nanoseconds resolution
//
// \return monotonic time stamp
//
static inline uint64_t clock_get_ns()
{
#ifdef __unix__
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ((uint64_t)(ts.tv_sec * 1000000000)) + (uint64_t)ts.tv_nsec;
#elif _WIN32
LARGE_INTEGER ts, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&ts);
return ((uint64_t)(ts.QuadPart * 1000000000)) / (uint64_t)freq.QuadPart;
#else
#error "OS not supported!"
#endif
}

#endif // HIGH_PRECITION_CLOCK_H
Loading