-
Notifications
You must be signed in to change notification settings - Fork 58
Fix VRPN, improve tracker layout #146
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
base: master
Are you sure you want to change the base?
Changes from all commits
7d6055a
a113e88
f359fe6
edff317
f8041bb
3d2fd03
2d78f52
fde501c
5aca323
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,14 @@ struct quat : gml::quat | |
| } | ||
| }; | ||
|
|
||
| // Converting from yaw (around Z), pitch (around Y), roll (around X) to quaternions. | ||
| // This a lot worse than the other way around and should be avoided. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on your definition of "worse", this might be exactly wrong. This way is a unique transformation (except for the fact that each rotation can be represented by exactly two quaternions), the other way around is not unique, since there are rotations that can have infinitely many yaw/pitch/roll representations. Really, the other way around should be avoided! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, of course. This is just plain wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, that should be the advice! |
||
| template <typename T> | ||
| ssr::quat ypr2quaternion(T yaw, T pitch, T roll) | ||
| { | ||
| return gml::qrotate(gml::vec3{roll, pitch, yaw}); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another way to write this is: return gml::qrotate(gml::radians(azimuth), {0.0f, 0.0f, 1.0f})
* gml::qrotate(gml::radians(elevation), {1.0f, 0.0f, 0.0f})
* gml::qrotate(gml::radians(roll), {0.0f, 1.0f, 0.0f});I have no clue whether those two are equivalent, because the order of rotations and the order of axes is not visible in the single call to I like having both orders visible. I don't know which one of the alternatives is faster, would be interesting to benchmark this ... |
||
| } | ||
|
|
||
| /// Build a unit quaternion representing the rotation | ||
| /// from u to v. The input vectors need not be normalised. | ||
| /// From http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -382,8 +382,10 @@ void ssr::QOpenGLPlotter::_draw_reference() | |
|
|
||
| glTranslatef(0.03f, -0.03f, 0.0f); | ||
|
|
||
| // rotate according to reference position | ||
| glRotatef(_scene.get_reference().orientation.azimuth, 0.0f, 0.0f, 1.0f); | ||
| // rotate according to reference offset position | ||
| glRotatef(_scene.get_reference().orientation.azimuth + | ||
| _scene.get_reference_offset().orientation.azimuth, | ||
| 0.0f, 0.0f, 1.0f); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As long as the "rotation" and the "rotation offset" are indistinguishable in the interface for the binaural renderer, I agree that adding both makes sense. But then you should also add "position" and "position offset". |
||
|
|
||
| glBindTexture(GL_TEXTURE_2D, _listener_shadow_texture); | ||
|
|
||
|
|
@@ -396,8 +398,10 @@ void ssr::QOpenGLPlotter::_draw_reference() | |
|
|
||
| glPopMatrix(); | ||
|
|
||
| // rotate according to reference position | ||
| glRotatef(_scene.get_reference().orientation.azimuth, 0.0f, 0.0f, 1.0f); | ||
| // rotate according to reference offset position | ||
| glRotatef(_scene.get_reference().orientation.azimuth + | ||
| _scene.get_reference_offset().orientation.azimuth, | ||
| 0.0f, 0.0f, 1.0f); | ||
|
|
||
| glBindTexture(GL_TEXTURE_2D, _listener_texture); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -980,8 +980,8 @@ void ssr::QUserInterface::mouseMoveEvent(QMouseEvent *event) | |
| // absolut mouse position in OpenGL coordinates | ||
| Position mouse_pos(static_cast<float>(pos_x), static_cast<float>(pos_y)); | ||
|
|
||
| // position relative to reference position | ||
| mouse_pos -= _scene.get_reference().position; | ||
| // position relative to reference position offset | ||
| mouse_pos -= _scene.get_reference_offset().position; | ||
|
|
||
| _get_openGL_pos(_previous_mouse_event.x(), | ||
| _previous_mouse_event.y(), | ||
|
|
@@ -990,11 +990,12 @@ void ssr::QUserInterface::mouseMoveEvent(QMouseEvent *event) | |
| // previous absolut position in OpenGL coordinates | ||
| Position prev_mouse_pos(static_cast<float>(pos_x), static_cast<float>(pos_y)); | ||
|
|
||
| // previous position relative to relative position | ||
| prev_mouse_pos -= _scene.get_reference().position; | ||
| // previous position relative to relative position offset | ||
| prev_mouse_pos -= _scene.get_reference_offset().position; | ||
|
|
||
| _controller.take_control()->reference_rotation(_scene.get_reference().orientation + | ||
| (mouse_pos.orientation() - prev_mouse_pos.orientation())); | ||
| _controller.take_control()->reference_rotation_offset(_scene.get_reference().orientation + | ||
| _scene.get_reference_offset().orientation + | ||
| (mouse_pos.orientation() - prev_mouse_pos.orientation())); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the mouse should affect the "rotation offset". Using the right mouse button doesn't affect the "position offset" either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I try rotating the head (using the binaural renderer), the orientation is jumping around eratically. Something is wrong there ... |
||
|
|
||
| } // else if | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,13 +30,46 @@ | |
| #ifndef SSR_TRACKER_H | ||
| #define SSR_TRACKER_H | ||
|
|
||
| #include <atomic> | ||
| #include <thread> | ||
|
|
||
| #include "geometry.h" | ||
|
|
||
|
|
||
| namespace ssr | ||
| { | ||
|
|
||
| /// Class definition | ||
| struct Tracker | ||
| class Tracker | ||
| { | ||
| virtual ~Tracker() = default; ///< destructor | ||
| public: | ||
| Tracker(api::Publisher& controller) : _controller(controller){}; ///< constructor | ||
|
|
||
| /// calibrate tracker; set the instantaneous position to be the reference | ||
| virtual void calibrate() = 0; | ||
| virtual ~Tracker() = default; ///< destructor | ||
|
|
||
| /// reset tracker; set the instantaneous position to be the reference | ||
| virtual void reset() | ||
| { | ||
| SSR_VERBOSE2("Tracker reset."); | ||
| this->_correction_rot = this->_current_rot; | ||
| } | ||
|
|
||
| // Update SSR | ||
| virtual void update() | ||
| { | ||
| ssr::quat r = inverse(_correction_rot) * inverse(_current_rot); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you call Shouldn't it be enough to call |
||
| _controller.take_control()->reference_rotation_offset(r); | ||
| } | ||
|
|
||
| protected: | ||
| // Current tracker data (should be atomic) | ||
| ssr::quat _current_rot; | ||
| ssr::quat _correction_rot; | ||
|
|
||
| private: | ||
| api::Publisher& _controller; | ||
| }; | ||
|
|
||
| } // namespace ssr | ||
|
|
||
| #endif | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is ambiguous and also not true.
ambiguous: the rotations are around the local coordinate axes (after the axes themselves have been rotated). I'm not sure what's the best way to say this un-ambiguously.
I personally find it better understandable to describe it as three global rotations in a given order (first "roll" then "pitch" then "yaw").
not true: "pitch" is a rotation around a local X axis, because the default orientation is "north".
At least that's how I think it should be in the SSR, other systems will differ.
This stuff is complicated, so I might well be totally wrong about it.
I think it's best just not to create an "official" function for it, since it's a one-liner anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see... I just ran into the same problem as in the GUI head-tracker PR earlier.
We have to document this somewhere. Really.
More specifically, the aerospace norm/ nautical angles.
At least for me, an airplane first yaws on ground, then pitches during take-off and then rolls around its forward (nose) axis.
We should also make sure to use this convention of YPR consistently across all trackers and maybe even the SSR. I'm not sure if this is the case atm. I thought that at least the Razor uses X-forward, Z-up and the YPR definition above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
My first attempt is there: https://audioscenedescriptionformat.readthedocs.io/en/latest/position-orientation.html
But this can be for sure improved, and we should mention it in the SSR docs somewhere.
Yeah, I prefer those, too. But there are still 6 possible conventions (not considering left-handed systems and not even considering where x, y and z point to in the real world).
I don't really like the aerospace convention because the z axis points down. I don't think that's intuitive in our situation and for our community.
I would hope that neither is ambiguous. Do you think it is?
I agree that north/east/south/west is a secondary way of looking at it, but it might still be helpful for some people.
And "north" is definitely more concise than "positive y axis".
And there is definitely a tradition of naming those things after compass directions, e.g. "ENU" and "NED" (see https://en.wikipedia.org/wiki/Axes_conventions).
I think that both are equally valid ways of describing the same thing.
For those tracker APIs that provide quaternions, this whole problem doesn't matter (except for left/right-handedness I guess).
For those that provide angles, we just have to figure out the convention used in their API and correctly convert it to
ssr::quatorssr::Rot.But each tracker might use their own convention, therefore I don't think it makes sense to provide a general "ypr2quat()" function.
Maybe. But that doesn't mean we have to use that convention for anything else.
It should really be an implementation detail of each tracker, the important thing is that we get a quaternion out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the meantime I've created a new page in the ASDF docs: https://audioscenedescriptionformat.readthedocs.io/en/latest/rotation-matrices.html
Please tell me your suggestions for improvements. I hope there are no ambiguities left.
At some point I'll probably make a similar page using quaternions, but I think the rotation matrix stuff might be easier to understand anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a page about quaternions: https://audioscenedescriptionformat.readthedocs.io/en/latest/quaternions.html