Direction and UP vectors from Quaternion

Hey guys.
I am trying to setup precise image capturing from Camera sensor.
I am a bit confused with the setup of direction and up vectors.
I know that I am able to grab 7th elements array: [position, x, y, z, w] of Camera’s view characteristics using Camera Transform tool.

(new users may embed only one media in the post…)

And then convert Quaternion (last 4 numbers in array: x, y, z, w) into Direction and Up vectors.

I have tried to use found in Internet formulas and there is no luck.
Then I have found in beamngpy library the useful method: compute_rotation_matrix from beamngpy.misc.quat.
In, general I created the following code:

from beamngpy.misc.quat import compute_rotation_matrix

matrix = compute_rotation_matrix((0.226881, -0.0176147, 0.0753748, 0.970842))

direction_vector = matrix[:, 2] 
up_vector = matrix[:, 1]

print(f"Direction: {direction_vector}")
print(f"Up vector: {up_vector}")

And then I put obtained values into Camera setup:

av_a = Vehicle("vehicleA", model="bollard")
    client_b = BeamNGpy("localhost", 64256)
    client_b.open(launch=False)
    running_scenario = client_b.scenario.get_current()
    running_scenario.add_vehicle(av_a, pos=(-760.29, 354.34, 157.5))
    print(running_scenario.name)
    camera = Camera(
        "camera1",
        client_b,
        av_a,
        update_priority=1,
        requested_update_time=0.00000001,
        pos=(0, 0, 3),
        dir=(3.88427683e-08, -4.43186255e-01,  8.96429553e-01),
        up=(-0.1543468,  0.8856874,   0.43787544),
        field_of_view_y=34.5,
        near_far_planes=(0.1, 500),
        resolution=(640, 640),
        is_streaming=True,
        is_render_colours=True,
        is_render_annotations=False,
        is_render_depth=False
    )

And the only thing which I received is sky

Obviously, it is not what I need.
In general, I would like to have the following picture. (the FOV here is 32)

Could you please guys suggest me the correct way how to setup Direction and Up vectors for Camera?

Hey guys, I have fixed everything. Now I got what I want.

My problem was taking of incorrect vectors after rotation matrix is calculated.
I took columns instead of rows.

This is correct approach to convert quaternion (screenshot below)

into direction and up vectors

import os
import random
import string
import time

from beamngpy import BeamNGpy, Vehicle
from beamngpy.misc.quat import compute_rotation_matrix
from beamngpy.sensors import Camera


def test_beamng(client, direction_vector, up_vector, rotation):
    random_letters = random.choices(string.ascii_letters, k=12)
    id = ''.join(str(x) for x in random_letters)
    av_a = Vehicle(id, model="bollard")
    running_scenario = client.scenario.get_current()
    running_scenario.add_vehicle(av_a, pos=(-759.563, 353.790, 156.493))
    camera = Camera(
        "camera1",
        client,
        av_a,
        requested_update_time=1,
        is_using_shared_memory=True,
        pos=(0, 0, 3),
        dir=tuple(direction_vector),
        up=tuple(up_vector),
        field_of_view_y=34,
        near_far_planes=(0.1, 500),
        resolution=(1920, 1080),
        is_streaming=True,
        is_render_colours=True
    )
    time.sleep(1)
    raw_readings = camera.poll()
    name = "images" + os.sep + str(rotation).replace(" ", "_") + ".jpg"
    image = raw_readings["colour"]
    rgb_im = image.convert('RGB')
    rgb_im.save(name)
    print(f"saved: {rotation}. {name}")


quart = [0.215377, -0.0215848, 0.097355, 0.971426]

client_b = BeamNGpy("localhost", 64256)
client_b.open(launch=False)
x, y, z, w = quart
matrix = compute_rotation_matrix((x, y, z, w))
z_vector_row = matrix[2]
y_vector_row = matrix[1]
test_beamng(client_b, y_vector_row, z_vector_row, quart)


2 Likes

hi @byzkrovnyi,

you can also check the Sensor Configuration Editor which is implemented in the World Editor. ADAS Sensor Configuration Editor
With this editor you can place and rotate sensors on vehicles and also on the environment.

2 Likes

Hi @FloF, thanks for advice.

But in my case I need setup everything through python. So, I need to set location, direction, up vectors and I cannot install sensors manually