phantom Documentation

You should always use libphantom, additionally, you may use phlib, which uses libphantom itself, so that you may not bother with it.

Libphantom is a basic (and simple) interface between phantom, kernel and the user process. Realize, that there is no other way to do so in this version (version for 2.6 linux) of phantom.

libph-test.c as an basic example of libphantom usage follows:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include <linux/types.h>

#include <sys/time.h>
#include <time.h>

#include <libphantom.h>

#define print2(args...) fprintf(stderr, args)

//#define SPHERE

#define N       64

static unsigned long frequency = 1000;
static float center[3];
static const double radius = 0.05;
static const float stiffness = 1000.0 / 2.0;

#ifdef SPHERE
static void object(struct phantom_info *p, float force[]) /* sphere */
{
        float x = p->actual.pos[0] - center[0];
        float y = p->actual.pos[1] - center[1];
        float z = p->actual.pos[2] - center[2];
        float n = x * x + y * y + z * z;

        if (n <= radius * radius) {
                double d = (n > 0.0001) ? (radius / sqrt(n) - 1) * stiffness :
                        10;
                force[0] = x * d;
                force[1] = y * d;
                force[2] = z * d;
        } else
                force[0] = force[1] = force[2] = 0.0;
}
#else
static void object(struct phantom_info *p, float force[]) /* plane */
{
        const float A = 0;
        const float B = 0;
        const float C = 1;
        const float D = -0.0;  /* select X m above zero */

        float delta = A * p->actual.pos[0] + B * p->actual.pos[1] +
                C * p->actual.pos[2] + D;

        if (delta > 0) {
                force[0] = force[1] = force[2] = 0;
        } else {
                /* we want opposite force depending on the
                   depth you are inside the sphere */
                delta = -delta * stiffness;
                force[0] = A * delta;
                force[1] = B * delta;
                force[2] = C * delta;
        }
}
#endif

static inline unsigned int print_rate(unsigned int i)
{
        return !(i % 10);
}

static void test(struct phantom_device *dev)
{
        struct phantom_info *p;
        unsigned int i, tm, maxtm;
        unsigned long it = 0;
        double speed[2*N], a[N];
        float force[3];

        tm = 0;
        maxtm = 1;

        memset(a, 0, sizeof(a));
        p = phm_switch(dev);
        memset(&p->force, 0, sizeof(p->force));

        phm_wait(dev);
        p = phm_switch(dev); /* get actual phantom position and set center */
        center[0] = center[1] = center[2] = 0.0;

        memset(speed, 0, sizeof(speed));

        dev->iterations = 1;
        for (i = 1; (!(dev->status & PHM_ERROR) && i < frequency * 15) ; i++) {
                /* wait for new data */
                phm_wait(dev);
                it++;
                p = phm_switch(dev);
                object(p, force);

                phm_force_clamp_max(force, PHM_DEFAULT_MAX_FORCE);

                memcpy(p->force, force, sizeof(force));

                if (print_rate(i)) {
                        printf("force:   %f  %f  %f\n", p->force[0],
                                        p->force[1], p->force[2]);
                }

                if (tm > maxtm)
                        maxtm = tm;

                if (print_rate(i)) {
                        printf("pos: %f  %f  %f\n", p->actual.pos[0],
                                        p->actual.pos[1], p->actual.pos[2]);
/*                      printf("ang: %f  %f  %f\n", p->actual.alpha,
                                        p->actual.beta, p->actual.gamma); */
                }
        }

        printf("Iterations: %lu   global iterations: %lu   diff: %lu\n",
                it, dev->iterations, dev->iterations - it);
        printf("Forces: %f %f %f \n", p->force[0], p->force[1], p->force[2]);
}

int main(int argc, char **argv)
{
        struct phantom_device *dev;
        char *devname = "/dev/phantom0";

        switch (argc) {
        case 2:
                devname = argv[1];
        case 1:
                break;
        default:
                print2("Bad arguments count!\n");
                goto err;
        }

        printf("devname: %s\n", devname);

        dev = phm_open(devname);
        if (dev == NULL) {
                print2("Can't open phantom!\n");
                goto err;
        }

        if (phm_reset(dev)) { /* this sould never happen :) */
                print2("Can't reset phantom!\n");
                goto err_stop;
        }

        if (phm_start(dev, 0)) {
                print2("Can't start phantom!\n");
                goto err_stop;
        }

        test(dev);

        phm_stop(dev);

        return 0;
err_stop:
        phm_stop(dev);
err:
        return 1;
}

Note the phm_reset() call. You may omit it, but in that case, be sure, that you've involved ph-reset binary (which does the job for you). It is necessary to reset phantom at least once before using.

Note, that phm_stop() is called even if phm_start() was not called in the case of phm_reset() failure. This approach is OK.


Generated on Thu Feb 21 14:57:45 2008 for phantom by  doxygen 1.5.5