[fusion_builder_container hundred_percent=”no” equal_height_columns=”no” hide_on_mobile=”no” background_color=”#20232c” background_position=”left top” background_repeat=”no-repeat” fade=”no” background_parallax=”none” enable_mobile=”no” parallax_speed=”0.3″ video_aspect_ratio=”16:9″ video_loop=”yes” video_mute=”yes” border_style=”solid” border_sizes_top=”0px” border_sizes_bottom=”0px” border_sizes_left=”0px” border_sizes_right=”0px” type=”flex”][fusion_builder_row][fusion_builder_column type=”2_3″ layout=”2_3″ spacing=”6%” center_content=”no” hover_type=”none” link=”” min_height=”” hide_on_mobile=”no” class=”” id=”” background_color=”” background_image=”” background_position=”left top” undefined=”” background_repeat=”no-repeat” border_color=”” border_style=”solid” border_position=”all” padding_top=”” padding_right=”” padding_bottom=”” padding_left=”” margin_top=”” margin_bottom=”40px” animation_type=”” animation_direction=”left” animation_speed=”0.1″ animation_offset=”” last=”true” first=”true” border_sizes_top=”0px” border_sizes_bottom=”0px” border_sizes_left=”0px” border_sizes_right=”0px” spacing_right=”4%” type=”2_3″][fusion_title title_type=”text” rotation_effect=”bounceIn” display_time=”1200″ highlight_effect=”circle” loop_animation=”off” highlight_width=”9″ highlight_top_margin=”0″ before_text=”” rotation_text=”” highlight_text=”” after_text=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” content_align_medium=”” content_align_small=”” content_align=”left” size=”2″ font_size=”28px” animated_font_size=”” fusion_font_family_title_font=”Montserrat” fusion_font_variant_title_font=”400″ line_height=”” letter_spacing=”” margin_top_medium=”” margin_bottom_medium=”” margin_top_small=”” margin_bottom_small=”” margin_top=”” margin_bottom=”30px” margin_top_mobile=”” margin_bottom_mobile=”” text_color=”” animated_text_color=”” highlight_color=”” style_type=”default” sep_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

Building a low cost DIY AR Headset

[/fusion_title][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

A few years back, Lenovo released an AR headset for under $200. You can now find the headsets for under $50 on ebay. The optics are pretty decent, estimate >60 degree FoV, minimal ghosting, tracking is not perfect, but for the price, it is pretty impressive. The only issue for me was that there was no SDK to use with Unity so I couldn’t create my own games for it. After playing around with the headset for a bit, I learned about its ‘bird bath’ optical combiner, which are essentially spherical mirrors that are in line with the viewing axis. This makes the distortion fairly easy to compute, and I decided to give it a try to see if I could create my own SDK for the Lenovo headset. Fortunately for me, I didn’t need to create this from scratch since there is an open source project called HoloKit that does a lot of the work for me. A few weeks later and some tinkering I had all the right parameters and was able to get pretty close to pixel accurate stereo vision on my cheap AR headset.

[/fusion_text][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

I still needed tracking though and the built in cameras wouldn’t work since they required a proprietary driver. I experimented using HTC vive tracker over the network and got that to work okay. The main issue is motion-to-photon latency when going over a network is pretty poor > 60ms. In order to achieve hololens style tracking, I would need to get this to be under 20ms. I began experimenting with pose-prediction, and modifying the render pipeline, similar to the way Oculus does Asynchronous Time Warp. I was able to predict the pose by between 2-3 frames which meant a effective reduction in latency by 16msx3=48ms. This was not bad, except when making quick movements with your head, the pose prediction fails and the result is objects that seem to move around in air and the sense of presence is lost.

[/fusion_text][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

In order to do better, I would need to develop my own tracking solution. This is not as easy as it sounds. One of the reasons Magic Leap and Hololens tracking is as good as it is, is because they have multiple sensors and are able to integrate the drivers at a very low level with the hardware, giving the tracking a higher priority on the CPU than other processes. Since I will be building my tracking at the application level, I’m already at a disadvantage. After pretty extensive research into various SLAM algorithms (Simultaneous Localization and Mapping), I opted for Visual Odometry using Open CV which I was able to implement in Unity with a little work. This allows me to achieve 60fps tracking, which means 16ms motion-to-photon latency without applying pose prediction. When I apply pose prediction, the tracking is nearly perfect and I’m able to achieve nearly hololens style tracking on a low cost <$100 headset!!

[/fusion_text][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

What does the final result look like? I made a video through the lens, so you are seeing actual motion-to-photon and not a video stream through software that can sometimes correct for latency.

[/fusion_text][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

Now that I had tracking solved, I wanted to add controllers. I happen to have access to HTC Vive controllers and trackers and so I began experimenting with those. The trick here is that I need to use the same world coordinates as the headset, and for this I needed to come up with a calibration procedure. I decided on using a 4-point calibration, which is better than 2-point, but of course, more points is better but also takes more time. By recording 4 points in terms of position and orientation, I can compute the transformation that converts one world coordinates into calibrated world coordinates. I found a library Mathematics.Net which provides me with SVD (Singular Value Decomposition) which is the technique to solve the parameters. Now that I can correct the world coordinates, everything lines up perfectly, I’m able to use the built in head tracking using the VO algorithm along with Vive trackers. The head tracking is extremely fast, no perceivable latency, and the controller latency is less critical, and very functional.

[/fusion_text][fusion_separator style_type=”none” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” class=”” id=”” sep_color=”” top_margin=”30px” bottom_margin=”” border_size=”” icon=”” icon_circle=”” icon_circle_color=”” width=”” alignment=”center” /][fusion_imageframe image_id=”1124|medium” max_width=”” sticky_max_width=”” style_type=”none” blur=”” stylecolor=”” hover_type=”zoomin” bordersize=”0px” bordercolor=”” borderradius=”0″ align_medium=”none” align_small=”none” align=”none” margin_top=”” margin_right=”” margin_bottom=”” margin_left=”” lightbox=”yes” gallery_id=”” lightbox_image=”” lightbox_image_id=”” alt=”” link=”” linktarget=”_self” hide_on_mobile=”no” sticky_display=”normal,sticky” class=”” id=”” animation_type=”” animation_direction=”down” animation_speed=”0.1″ animation_offset=”” filter_hue=”0″ filter_saturation=”100″ filter_brightness=”100″ filter_contrast=”100″ filter_invert=”0″ filter_sepia=”0″ filter_opacity=”100″ filter_blur=”0″ filter_hue_hover=”0″ filter_saturation_hover=”100″ filter_brightness_hover=”100″ filter_contrast_hover=”100″ filter_invert_hover=”0″ filter_sepia_hover=”0″ filter_opacity_hover=”100″ filter_blur_hover=”0″]http://teleprezi.com/wp-content/uploads/2016/01/IMG_20190715_125501-300×225.jpg[/fusion_imageframe][fusion_separator style_type=”none” top_margin=”60px” bottom_margin=”” sep_color=”” border_size=”” icon=”” icon_circle=”” icon_circle_color=”” width=”” alignment=”center” class=”” id=”” /][fusion_text columns=”” column_min_width=”” column_spacing=”” rule_style=”default” rule_size=”” rule_color=”” content_alignment_medium=”” content_alignment_small=”” content_alignment=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” sticky_display=”normal,sticky” class=”” id=”” font_size=”” fusion_font_family_text_font=”” fusion_font_variant_text_font=”” line_height=”” letter_spacing=”” text_color=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]

If I get time, I’ll package the project up and either share on github or asset store.

[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]