weekly meeting with my supervisor

Today we talked about the report:

- how and what I need to reference

- what I should put in my design / analysis parts

- how and where to use UML diagrams.

At the moment I have finished to write the first draft of the abstract, introduction, analysis and design parts.

I am now going to work on the modifications we talked about during the meeting.

I also need to work on finding some more references.

I’ll then start working on the implementation part.

Meeting with my supervisor

This week we talked again about the report, I’ve asked my supervisor to check my table of contents to be sure I was covering everything.

The big sections of my report will be :

- Introduction

- Analysis

-Design

-Implementation

- Feedback/ Testing

- Conclusion

We also discussed what each section should content.

I have now finished to write the abstract and introduction, so now I’m now going to start writing the Analysis and Design parts.

Meeting with my supervisor

Today I showed my supervisor the demonstration applications I used last week during my presentation at Schlumberger.

I also told him I had decided to stop coding on the project. Here are the main reasons :

- The final year project handbook says students are supposed to work 20 hours per week on their final year project (and 10hours per week for each of the other modules), over a period of 20 weeks. Which makes a total of 400 hours for the whole project. So far I’ve spent at least 800 hours on the project (report not included). Also I have four other modules, on which I should have worked 40hours per week but I didn’t.

- The marks : even if it was not my main objective until now, I need to remember that the objective of the year is to get a first class degree. And for that it makes much more sense to work on the other modules than on the final year project, for the simple reason that the implementation only represents 30% of the marks.

So from now on I will only work on the report and the other modules and won’t be changing the code any more.

My supervisor didn’t tell me if it was a good idea or not to stop the development, he just told me that I still had to keep a schedule for the remaining weeks.

Also, from now on we will only meet if needed (I won’t go every week as I used to).

Here is the schedule for next week : I’m going to start writing the abstract and the introduction parts of my report.

Schlumberger visit #3

yesterday and today I was in Cambridge to give a presentation of the API, give them the source code, and debug the VR part.

It didn’t really go according to the plan: I spent all thursday and friday fixing bugs and trying to loading new datasets in order to have some more interesting data to show during the presentation.

As a result I didn’t work at all on the VR part.

I now have several scenes : 3 using some simulated data, and 1 using some real data.

The presentation went well, about 10-15 people intended, and they all seemed impressed by the demonstration.

During the meeting we discussed about the future of the project :

- I won’t modify the code any more.

- They don’t really know how they want to make the library evolve. So, in the next few months they’re going to use it, and after they will start thinking about possible improvements or new features.

- Some people suggested to transfer the project to the Visualisation intern

- My project report will be the only developer documentation available.

New features

Over the past few days :

- I’ve implemented a very basic VR mode : asymmetric frustum for the head tracking, stereo display, wand input to control the camera and the time. But this has not been tested yet so it’s hard to tell the current status of the VR part.

- I’ve implemented a graph view : basically you have a rectangle surface on which you can plot graphs, and animate it at the same time as the other objects in the scene. You can also zoom in / out on one axis or both.

- I’ve added a bit of shading on the BHA so that it looks less flat.

- I’ve created a binary serializer / loader for the data files (Float list and Double list), the only files which can’t be serialized as binary are the bha composition files, but it’s not a problem as they are really small (~10kB)

I’ve debugged the multi threading and the multi windows system : now you can create as many 3D popup windows as you want, and use different cameras in each of them. (I’ll post a video of that later)

I’ve added several functions to the C Interface. (I still need to document it though)

To do next :

- debug the borehole generation : still have some twists problems.

- add the new functions to the Matlab interface

- work on the documentation of both the interfaces.

- Improve a bit the GUI.

- Fly mode camera (for the VR)

Stereoscopic display

In the past I was using Open Scene Graph when I wanted to display something in stereo, so I don’t know how to do it just with OpenGL.

I’ve done some research and here are a few useful links :

- This guy did a lot of work about stereographics, and he also put some OpenGL code :

http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/stereographics/stereorender/

http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/stereographics/ 

- I need to use Active Stereo, and the only way I know to do that is to use the Quadro FX driver from nVidia : http://www.nvidia.com/object/quadro_stereo_technology.html

Here is what I’ve found on the forum nvidia :

“This is correct. Stereo support is one of the selling points of the Quadros. The specific feature is called quad buffers. That is; left and right front and back buffers.
To use quad buffers, first select a pixel format with quad buffers/stereo support.
Then use glDrawBuffer(GL_BACK_LEFT/GL_BACK_RIGHT) to select the buffer. No openGL extensions or special API needed.”

http://developer.nvidia.com/forums/index.php?showtopic=3007

So, apparently I just need to set the “stereo” flag in my pixel format when the OpenGL context is created (which means using WX_GL_STEREO : http://docs.wxwidgets.org/2.8/wx_wxglcanvas.html)

and then I need to render twice the scene using glDrawBuffer(GL_BACK_LEFT) and glDrawBuffer(GL_BACK_RIGHT) , like this :

http://www.orthostereo.com/geometryopengl.html  

GLvoid display(GLvoid)
{
  glDrawBuffer(GL_BACK);                                   //draw into both back buffers
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);      //clear color and depth buffers

  glDrawBuffer(GL_BACK_LEFT);                              //draw into back left buffer
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();                                        //reset projection matrix
  glFrustum(leftCam.leftfrustum, leftCam.rightfrustum,     //set left view frustum
            leftCam.bottomfrustum, leftCam.topfrustum,
            nearZ, farZ);
  glTranslatef(leftCam.modeltranslation, 0.0, 0.0);        //translate to cancel parallax
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity);
  glPushMatrix();
  {
    glTranslatef(0.0, 0.0, depthZ);                        //translate to screenplane
    drawscene();
  }
  glPopMatrix();

  glDrawBuffer(GL_BACK_RIGHT);                             //draw into back right buffer
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();                                        //reset projection matrix
  glFrustum(rightCam.leftfrustum, rightCam.rightfrustum,   //set left view frustum
            rightCam.bottomfrustum, rightCam.topfrustum,
            nearZ, farZ);
  glTranslatef(rightCam.modeltranslation, 0.0, 0.0);       //translate to cancel parallax
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity);

  glPushMatrix();
  {
    glTranslatef(0.0, 0.0, depthZ);                        //translate to screenplane
    drawscene();
  }
  glPopMatrix();
  
  glutSwapBuffers();
}

I don’t remember what kind of grpahics card we have in the lab, so I’m not sure I’ll be able to test it here. I need to check that.

Virtual Reality / VRJuggler

This week end I’ve started to work on the Virtual Reality part of the API,  and more specifically on the tracking system.

The first step is to be able to read the data from the tracking system.

In the past I’ve used VRJuggler , this is an open source framework dedicated to Virtual Reality. It’s really flexible (this is the most flexible library I’ve ever used), and it’s supporting the Intersense IS900 tracking system (which is what Schlumberger has in its iCenter).

As I said I knew this API before I started the project, but I decided not to use it to handle the graphics part because it can’t be link statically and so it would have implied a lot of DLL to distribute with the library which is exactly what I wanted to avoid.

Compilation

So, first I had to recompile VRJuggler because there are no binaries for Visual Studio 2008, this took me ages to do because there are a lot of projects inside the solution and a lot of paths to set.

Fortunately, I’ve found on internet a link to a large zip file containing all the dependencies  (compiled with VS 2008) for the library (375 MB !), so thanks a lot to the person who did that, I would have probably not had the time to do it myself.

Both Debug and Release versions compiled fine, but for some reasons only the Release version is working, the debug version crashes at initialization. I decided not to waste time on making the Debug version work because it’s not really important.

Environment variables

The main drawback of VRJuggler is that it depends on a lot of environment variables for the path. The reason is the library is so flexible that it requires to load a lot of config files at runtime. I really wanted to avoid using environment variables because it would have meant installing VRJuggler on the client machine, which is not really a good option.

After looking into the API code, I managed to find how to force it to use relative paths for the different files it needed. So now there is no need to install the whole VRJuggler package ! (I still need to test it on another computer to be 100% sure).

Config files

VRJuggler loads the hardware configuration from one or several “jconf” files at runtime (These are XML files), and there is a tool called VRJConfig to help generating them.And here is the second biggest drawback of VRJuggler : this is so flexible that the config files are quite complicated to generate, even with VRJConfig… (you need to set the drivers, the hardware, to create some proxys, windows, aliases,…)

And VRJConfig is a bit buggy too: it won’t save the configuration properly all the time, sometimes it writes, sometimes it doesn’t…

So, after a few hours spent on the configuration ( don’t forget I’ve already done once during my placement, I let you imagine what it was like the first time…), I managed to generate 2 configuration files :

- “intersense.jconf” : this is the config file to read the tracking system data directly from the COM port. (You can find here the 3 different ways to get IS900 data, basically you can : read from the COM port using VRJuggler driver, read from the COM Port using the Intersense API,  read the data from the Intersense Trackd Server). I decided to use VRJuggler’s driver.

- “intersenseSimu.jconf” : this is a config file which simulates an IS900 device and so I can change the device values using the keyboard.

VRJuggler Kernel

VRJuggler is using a system of kernel, this means there is no “main” function, instead we create a class which inherits from one of VRJuggler kernel class and we overload the methods we want.

At the initialization VRJuggler will start the kernel in a new thread.

I’ve written a new kernel based on the “Simple Input” example provided with the SDK and on the work I’ve done during my placement.

TrackingDLL

I’ve now started to write a DLL, it has a C interface. This way it can dynamically be loaded by the main API without having to recompile.

The interface allows the user to :

- start / stop the tracking system

- get the data for the 2 position devices (head / wand), 2 analogic buttons (joystick x and y axis), 6 digital buttons (red,green,blue, yellow, trigger, joystick).

BHA representation problems

I’ve now moved all the direction computations to double precision (so I can match the same accuracy as in the data files), but even with that I still have two major problems :

- According to the data some short components (0.01 meters) have an orientation different of 90 degrees with the previous/next component, and their diameter is so big compared to their length (0.15  meters) that it should be physically impossible to fit. Here is a screenshot of what I’m talking about : (I’ve removed the liaisons between the cylinders so that you can better see the components) :

And here is a screenshot when I use my algorithm to reduce the overlapping between the cylinders (as you can see it’s still not enough to solve the collision problems) :

- Second problem : I know some components are meant to be deformed, but in this case it seems weird : the size of the component is multiplied by 10 (usually it’s 0.1 and it’s extended to 1), and also all the components seem to extend when they arrive at the same point.

TIME,NODE,EW,NS,TVD,Rot
t,n,m,m,m,deg
7,1,-122.60000503,105.30006290,2222.00000000,0     ==> Time 7, there is 0.1 meter between nodes 1 and 2
7,2,-122.60000284,105.30006992,2221.99999931,0

9,1,-122.70001239,105.40006676,2223.00000000,0    ==> Time 9, there is more than 1 meter between the nodes 1 and 2
9,2,-122.70001286,105.40007063,2221.99999931,0

Here are two screenshots and a video to explain :

In this video you can see that each component arriving to the same point will be extended in the same way :

Multi threading / asynchronous mode

Today i’ve added a multi threading option to my API :

instead of calling “init()” at the beginning, the user can call “initNewThread()”, which will launch the API and start refreshing the window in a secondary thread.

After that the user can load the trajectory, borehole, bha etc… from the main thread, and still use the window at the same time.

Also, the user can programmatically control the window( Like setting the time for example) without having to handle the refresh loop (like it was before).

Finally, I’ve added a progress bar and an “abort” button in order to follow the loading process and be able to cancel if it’s too long.

Problems encountered

My classes were not thread safe (the mutex were not used correctly, for example I was locking a resource,returning a reference, unlocking the resource, and then using the reference.) So now this is all fixed. (I’ve added explicit functions to lock /unlock the data)

OpenGL calls can only be made from the thread in which the OpenGL context has been created, 2 solutions to fix this problem :

- create a second context in the second thread and share the resources: this solution was not easy to implement with my design (the opengl context is managed by wx, so I should have created a new window, and also it means I should check before each openGL call that the right context is active).

- send messages to the thread which can use opengl so that it makes the call for the other thread : this is the solution I’ve implemented; at the beginning of each “update” loop the secondary thread check if there are some opengl requests coming from the other thread. In the meantime the other thread is blocked and wait for the other thread answer.

So far it’s working fine like this.

There are two problems left :

- when I close the application the two threads don’t seem to synchronize correctly.

- the shaders don’t seem to work for the moment.

I’ll check that tomorrow.

Borehole / BHA / Trajectory debugging

I’ve fixed some of the bugs I was talking about in the previous post :

- The trajectory : just by increasing the “SegmentSize” property of the curve the bug disappears.

- The borehole : I’ve added a property called “DistanceDirection”. This property uses an averaged direction instead of the real direction when the points are too close.

For example, DistanceDirection = 10.f : if the distance between the p0 and p1 is > 10 => we keep the vector p0p1 as the direction.

the distance between p0 and p1 <10, and if the distance between p0 and p2 <10 too, but the distance between p0 and p3 > 10, then we take the average of p0p1, p0p2, p0p3 as the direction.

Here is the screenshot of the old method :

And here is the new method result :

- The BHA : With the previous dataset all the BHA components were almost aligned so I hadn’t this problem, but now there are some steep angles between two consecutive cylinders, which means there are collisions :

I wrote an algorithm to move cylinders out of each other, without changing the direction of the components :

“P” is the common point to both the cylinders,

V0 is the direction vector from P to the other extremity of the first cylinder.

V1 is the direction vector from P to the other extremity of the second cylinder.

V2 is the normal of the plane containing V0,V1 and P ==> V2 = cross(V0,V1)

V00 is a vector normal to V0 in this plane, its length is the radius of the cylinder 0 : V00 = cross(V0,V2) * Radius_0

V11 is a vector normal to V1 in this plane, its length is the radius of the cylinder 1 : V11 = cross(V1,V2) * Radius_1

Now we want to move each cylinder along its axis of the same distance so that we only have one point of contact left :

t * V0 + V00 = t * V1 + V11

t –  t * ( V1 / V0 = (V11 – V00) / V0

t = (V11 –  V00) /  ( V0 – V1)

We now move the points of each cylinder along their respective axis of “t” times the cylinder direction

Here is the result :

Problems left :

There are still a lot of bugs on the BHA, I think it’s because of the data : some cylinders are very short, and at some points during the drilling operation they are compressed, as a result I get some cylinders like this :

4,3,-122.39998021,105.10011940,2221.99999899,0
4,4,-122.39997963,105.10012920,2221.99999891,0

This is impossible to use this to compute the orientation of the component.

This is an accuracy problem, so I can’t really see any solution to that.

Follow

Get every new post delivered to your Inbox.