Strange quaternion rotation from Nicla Sense and Three.js

I'm using this code to receive sensor data:

#include "Nicla_System.h"
#include "Arduino_BHY2.h"

Sensor temperature(SENSOR_ID_TEMP);
Sensor humidity(SENSOR_ID_HUM);
Sensor pressure(SENSOR_ID_BARO);
Sensor gas(SENSOR_ID_GAS);
SensorXYZ gyroscope(SENSOR_ID_GYRO);
SensorXYZ accelerometer(SENSOR_ID_ACC);
SensorQuaternion quaternion(SENSOR_ID_RV);
SensorBSEC bsec(SENSOR_ID_BSEC);

void setup(){
  Serial.begin(115200);

  Serial.println("Start");

  nicla::begin();
  nicla::leds.begin();
  nicla::leds.setColor(green);

  //Sensors intialization
  BHY2.begin();
  temperature.begin();
  humidity.begin();
  pressure.begin();
  gyroscope.begin();
  accelerometer.begin();
  quaternion.begin();
  bsec.begin();
  gas.begin();

  if (!Serial){
    Serial.println("Failled to initialized SERIAL!");

    while (1)
      ;
  }
}

void loop(){
  while (Serial){
    BHY2.update();
    Serial.println(String("Qx: ") + quaternion.x() + String("\t") + String("Qy: ") + quaternion.y() + String("\t") + String("Qz: ") + quaternion.z() + String("\t") + String("Qw: ") + quaternion.w());
  }
}

And this is Three.js script adapted from here:

// 3d model
var renderer = new THREE.WebGLRenderer();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 1, 1, 10000);

var container = document.getElementById('3d');
var loader = new THREE.GLTFLoader();
var canvasDigits = document.getElementById('canvasDigits');
scene.background = new THREE.Color(0x58585A);
renderer.setSize(400, 400);

renderer.setPixelRatio(4);

container.insertBefore(renderer.domElement, canvasDigits);
renderer.domElement.style.margin = "9px";
loader.load('niclaSenseME.glb',
    // called when the Arduinio model is loaded
    function(gltf) {
        // Model
        arduinoModel = gltf.scene;
        scene.add(arduinoModel);

        // LED
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        ledMaterial = new THREE.MeshBasicMaterial({
            color: 0x111111
        });
        ledObject = new THREE.Mesh(geometry, ledMaterial);
        ledObject.position.set(9, -10, -1);

        ledLight = new THREE.PointLight(0x111111, 3, 40);
        ledLight.color.setRGB(0, 255, 0);
        ledLight.position.set(9, -10, -1.2);

        ledMaterial.color.setRGB(0, 255, 0);

        arduinoModel.add(ledObject);
        arduinoModel.add(ledLight);

        arduinoModel.rotation.x = 90 * (Math.PI / 180); // Show the bottom side of the board by default

        var sphereSize = 1;

        // Light
        const color = 0xFFFFFF;
        const intensity = 1;
        const light = new THREE.DirectionalLight(color, intensity);
        light.position.set(-20, 100, -10);
        light.target.position.set(0, 0, 0);
        scene.add(light);
        scene.add(light.target);
        var hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 1);
        scene.add(hemiLight);

        // Camera
        camera.position.set(0, 25, 0);
        camera.rotation.y = Math.PI; // 180
        camera.lookAt(new THREE.Vector3(0, 0, 0));
        renderer.render(scene, camera);
    }
);

function render() {
    requestAnimationFrame(render);

    // Construct the quaternion object with the values and apply that to the 3D model
    const quaternion = new THREE.Quaternion(qX, qY, qZ, qW);
    quaternion.normalize();
    arduinoModel.setRotationFromQuaternion(quaternion);

    renderer.render(scene, camera);

    // Euler conversion, show the degrees below the 3D model
    var rotation = new THREE.Euler().setFromQuaternion(quaternion, 'XYZ');
        document.getElementById('xQuaternion').innerHTML = "x: " + Math.round(rotation.x * 180 / Math.PI + 180);
        document.getElementById('yQuaternion').innerHTML = "y: " + Math.round(rotation.y * 180 / Math.PI + 180);
        document.getElementById('zQuaternion').innerHTML = "z: " + Math.round(rotation.z * 180 / Math.PI + 180);
}

render();

I don't know what I am doing wrong and I don't know how to proper align the Nicla quaternion with the 3D object.
Any help will be greatly appreciated.

You need to completely understand how the world and body (sensor) coordinate systems are defined and how they are related to each other.

The display software may use yet other definitions, so start by making sure that you understand and agree with the orientation information that the sensor is providing.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.