Rift Pi - Raspberry Pi apps for the Rift

severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

Geekmaster, I just received my PI and started hacking with my Rift. I wondering if you had made more progress on your end? Are you able to share some functional code, even if very hacky? I would love to experiment
geekmaster
Petrif-Eyed
Posts: 2708
Joined: Sat Sep 01, 2012 10:47 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by geekmaster »

Most of my spare thought time has been directed toward a Euclieon clone these days, with a bit going toward contstrained head position tracking. It would be cool to support the Pi too. I have a Ouya now too, so portability is important. Too many projects in progress... Yes, more on the Pi soon too...

I will try to find some of my hacky unfinished Pi code...
geekmaster
Petrif-Eyed
Posts: 2708
Joined: Sat Sep 01, 2012 10:47 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by geekmaster »

severan wrote:... Are you able to share some functional code, even if very hacky? I would love to experiment
Here is the ("very hacky") code for the downloadable pixelpi demo from an earlier thread. This was built using the libovr_nsb library posted at the oculusvr forums.

pixelpi.c:

Code: Select all

/*
 * pixelpi.c
 *
 * Distributed in the hope that this will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/epoll.h>

#include "OVR.h"

#define RIGHT_EYE_SHIFT 90
#define PPD 12

// 'global' variables to store screen info
char *fbp=0;
char *wbp=0;
int ystride=0;
long int screensize = 0;
struct fb_var_screeninfo orig_vinfo;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
int fbfd = 0;
Device *dev;
int xscale,yscale,xoffset,yoffset;

void draw() {
    int x, y, wx, wy, px, py;
    int r, g, b, a;
    int dr, sq;
    static frames=0;

    frames++;

    px=dev->Q[1]*xscale;
    py=dev->Q[3]*yscale;

    //printf("xres=%d, yres=%d, bpp=%d, stride=%d\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel, ystride);

    memset(wbp,0,screensize);
    if (vinfo.bits_per_pixel == 32) {
        for (y=0; y<vinfo.yres; ++y) {
//            for (x=0; x<ystride/4; ++x) {
            for (x=0; x<vinfo.xres; ++x) {
                wx=x+px;
                wy=y+py;
//		  if (wx&3 || wy&3) continue;
//		  r = (wx^wy)&255; g = ((wx/2)^wy)&255; b = (wx^(wy/2))&255;

		sq = (x+px)*(y+py);
		if ((sq&255) < 17) {
                  r=(sq-frames*2+(x+px)/32+(y+py)/64)&255;
                  g=((x+px)/2-frames*4)&255;
                  b=((y+py)/2-frames*3)&255;
		  //if (wx<-500 || wx>500 || wy<-500 || wy>500) {
                //    r/=4;g/=4;b/=4;
                //}
                *((unsigned int*)(wbp+x*4+y*ystride))=((0xff00+b<<8)+g<<8)+r;
          	}

            }
        }
    }

    memcpy(fbp,wbp,screensize); // change to a pair of eye blits

    //for (y<0;y<vinfo.yres;++y) {
    //    memcpy(fbp+y*ystride,wbp+y*ystride,ystride); // change to a pair of eye blits
    //}
}

void myinit(void)
{
    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);
    if (!fbfd) {
      printf("Error: cannot open framebuffer device.\n"); getchar();
    } else {
      printf("The framebuffer device was opened successfully.\n");
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
      printf("Error reading variable information.\n"); getchar();
    }
    printf("Original %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, 
       vinfo.bits_per_pixel );

    // Store for reset (copy vinfo to vinfo_orig)
    memcpy(&orig_vinfo, &vinfo, sizeof(struct fb_var_screeninfo));

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
      printf("Error reading fixed information.\n"); getchar();
    }

    vinfo.xres = 1280;
    vinfo.yres = 800;
    vinfo.bits_per_pixel=32;
    if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)) {
        printf("Error setting new variable information.\n"); getchar();
    }
    ystride=finfo.line_length;

    // map fb to user mem 
//    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
    screensize = vinfo.yres * ystride;
    printf("stride=%d, screensize=%d\n", ystride, screensize);
    fbp = (char*)mmap(0, 
              screensize, 
              PROT_READ | PROT_WRITE, 
              MAP_SHARED, 
              fbfd, 
              0);

    if ((int)fbp != -1) wbp=malloc(screensize);

    xscale = -180 * PPD;
    yscale = 90 * PPD;
    xoffset = -200;
    yoffset = -200;
}

// never called. need atexit().
void myclean(void) {
    free(wbp);
    munmap(fbp, screensize);
    ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo);
    close(fbfd);
}


/////////////////////////////////////////////////////////////////////////////////////
// Continuous sample/update thread code
// select() chosen for portability
/////////////////////////////////////////////////////////////////////////////////////
void *threadRun( void *data )
{
    Device *dev = (Device *)data;
    fd_set readset;
    struct timeval waitTime;

    // 500ms
    waitTime.tv_sec = 0;
    waitTime.tv_usec = 500000;

    FD_ZERO(&readset);
    FD_SET(dev->fd,&readset);

    sendSensorKeepAlive(dev);

    while( dev->runSampleThread ) {
        waitTime.tv_sec = 0;
        waitTime.tv_usec = 500000;
        int result = select(dev->fd + 1, &readset, NULL, NULL, &waitTime );

        if ( result && FD_ISSET( dev->fd, &readset ) ) {
            sampleDevice(dev);
        }
        // Send a keepalive - this is too often.  Need to only send on keepalive interval
        sendSensorKeepAlive(dev);
    }
    return 0;
}

//-----------------------------------------------------------------------------
// Name: main( )
// Desc: entry point
//-----------------------------------------------------------------------------
int main( int argc, char ** argv )
{
    dev = openRift(0,0);
    if (!dev){
        printf("Could not locate Rift\n");
        printf("Be sure you have read/write permission to the proper /dev/hidrawX device\n");
        return -1;
    }

    myinit();

    printf("Device Info:\n");
    printf("\tname:     %s\n", dev->name);
    printf("\tlocation: %s\n", dev->location);
    printf("\tvendor:   0x%04hx\n", dev->vendorId);
    printf("\tproduct:  0x%04hx\n", dev->productId);

    printf("CTRL-C to quit.\n\n");

    // Run a thread
    pthread_t f1_thread; 
    dev->runSampleThread = TRUE;
    pthread_create(&f1_thread,NULL,threadRun,dev);
    for (;;){
        draw();
    }
    myclean();
    return 0;
}
Makefile:
INCLUDES += -Ilibovr_nsb -Igl-matrix.c
CFLAGS = -fPIC -g

.c.o:
${CC} $(CFLAGS) -c ${INCLUDES} $<

LDFLAGS=

#LIBS= -Llibovr_nsb -lovr_nsb -Lgl-matrix.c -lgl-matrix -lglut -lGL -lGLU -lpthread -lm
LIBS= libovr_nsb/libovr_nsb.a gl-matrix.c/libgl-matrix.a -lm
THREADS=-lpthread

all: extralibs pixelpi

pixelpi: pixelpi.o
$(CC) $< $(LDFLAGS) $(LIBS) $(THREADS) -o $@

extralibs:
make -C gl-matrix.c
make -C libovr_nsb

clean:
rm -f *.o pixelpi
make -C gl-matrix.c clean
make -C libovr_nsb clean
Note that head tracking just follows a couple of coordinates of the quaternion, so the head swings in an arc when you rotate. It really needs to be converted to Euler... It is just a quick unfinished "proof of concept" hack to demo reading head tracker data in a semi-immersive way (based roughly on how GMsphere works).
severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

thanks, started hacking. I am getting some libovr_nsb error, have you faced it ?
libovr_nsb-0.3.0.so: cannot open shared object file: No such file or Directory

I am also gettting a compile time error, which might be related. complaining that device has no member named "location"
geekmaster
Petrif-Eyed
Posts: 2708
Joined: Sat Sep 01, 2012 10:47 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by geekmaster »

I used an older version. I had to build the library first (different Makefile). That seems to be what may be missing here. There was a discussion in the thread for that lib over at oculusvr. It worked for me, but I had to install the some packages on my RasPi as I recall... And run as root... There is a downloadabe executable in an eariler post, if you want to try my build...
severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

ok I got things going further. Compile and run but the sampling of the usb device does not work.
its interesting to note that the code you posted does not contain the "Sensor data" dump code.
Have you modified the code since then ?
severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

Ok I am good , got things working. I ll report on further progress
geekmaster
Petrif-Eyed
Posts: 2708
Joined: Sat Sep 01, 2012 10:47 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by geekmaster »

severan wrote:Ok I am good , got things working. I ll report on further progress
That pixelpi program was code snippets thrown together from various sources. I did remove some extraneous testing code and commented-out sections from it before posting. Perhaps there could have been minor differences since I posted the binary.

It runs from ssh root, and writes on the screen (overwriting desktop pixels). Simple demo of reading head tracker data and displaying something (sort of) head tracked on the Rift...

Like I said, instead of converting from Quaternion to Euler, I just borrowed a couple of quaternion terms to control yaw and pitch (in a non-linear way), and it worked well enough to show that both reading the head tracker and drawing on the display worked...

Glad you got it working... Now, let's see how far you can stretch it into something interesting. :D
severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

Looking into hacking pi3d, in another thread you quoted:
I found a configuration script for the RasPi that makes it display the desktop in SBS-Half format, which might work okay with the Rift, or with a tablet based HMD (after pre-warp is added).
http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=16577

Do you have more info on the above?
geekmaster
Petrif-Eyed
Posts: 2708
Joined: Sat Sep 01, 2012 10:47 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by geekmaster »

severan wrote:Looking into hacking pi3d, in another thread you quoted:
I found a configuration script for the RasPi that makes it display the desktop in SBS-Half format, which might work okay with the Rift, or with a tablet based HMD (after pre-warp is added).
http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=16577

Do you have more info on the above?
I just googled "raspberry pi half width desktop" and found this:
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=35&t=10402 wrote:... If you go settings and video modes, and choose the half-width mode, (e.g. 960x1080) that should automatically activate 3D mode in the TV, and should mean the GUI is duplicated side-by-side so it looks right. Then play your file. ... Thank you! The first tip worked just fine!
More digging could probably find the config script I mentioned, but that quote may provide enough hints to help you create a half-width modeline...
severan
One Eyed Hopeful
Posts: 6
Joined: Sat Aug 03, 2013 5:27 pm

Re: Rift Pi - Raspberry Pi apps for the Rift

Post by severan »

Update, I got a pretty cool demo going with pi3d library.
Basically modified the earth.py to support head tracking and mulltiple viewports (left and righ eye). Works great with a convincing 3d effect. I am trying to model the lens distortion now. Have you come across a deformation shader compatible with opengl es ?
Post Reply

Return to “Oculus VR”