Phil 1.3.13

8:00 – 4:00 ESSO

  • Viz Tool meeting
    • Found a date bug that we’re going to try to fix by Friday’s meeting
    • Reset all the alert states to acknowledged, to keep the users from going crazy
    • Need to add a way of acknowledging more than one alert. My thought is that we have a table that has the number of alerts that can show before an “acknowledge all” button is shown, and a MOTD list that can contain messages such as the state of the system. Maybe even something that has to be acknowledged.
    • Need to add a way to indicate that it’s time to enter data, but not an “overdue” flag.
  • Backups
  • Need to do a status report. Done
  • Worked out how to handle items in PA, when it is time to enter them, but they are not overdue. The states will now be as follows:
    • Current. Everything is filled in
    • Incomplete. Something is filled in, and the item is not overdue
    • Due. It is time to fill out the item (i.e. Between the 1st and 17th of the month is the “Due” period for the previous month
    • Overdue. An item that does not have all fields filled in that is past the “Due” date (i.e. the 17th)
  • Finished up my security briefings and emailed a scan of the signed form to Carrie.
  • Burned a disc containing PA and status for tomorrow.

4:00 – 5:00 FP

  • Got the callback working.
  • Pulled out setup(), run(), and terminate() methods. Next, I need to play around with the forces and make a moving object. Ideally, I’d like to have the rotating cube pair from the KF demo, but I’ll have to find some good cube code. I might start with spheres. Once I get the collisions behiving in a way that I like, I’ll start trying to add the code to (a copy of!) the KF demo

Header file:

class GravityWellClass
{
public:
	GravityWellClass(void);
	~GravityWellClass(void);

	bool setup();
	bool run();
	bool terminate();

protected: 
	HDErrorInfo error;
	HDSchedulerHandle hGravityWell;
	HHD hHD;

	static HDCallbackCode HDCALLBACK gravityWellCallback(void *data);
};

the callback method:

HDCallbackCode HDCALLBACK GravityWellClass::gravityWellCallback(void *data)
{
	const HDdouble kStiffness = 0.075; /* N/mm */
	const HDdouble kGravityWellInfluence = 40; /* mm */

	/* This is the position of the gravity well in cartesian
	   (i.e. x,y,z) space. */
	//static const hduVector3Dd wellPos = {0,0,0};
	hduVector3Dd wellPos;

	HDErrorInfo error;
	hduVector3Dd position;
	hduVector3Dd force;
	hduVector3Dd positionTwell;

	HHD hHD = hdGetCurrentDevice();

	/* Begin haptics frame.  ( In general, all state-related haptics calls
	   should be made within a frame. ) */
	hdBeginFrame(hHD);

	/* Get the current position of the device. */
	hdGetDoublev(HD_CURRENT_POSITION, position);

	memset(force, 0, sizeof(hduVector3Dd));

	/* >  positionTwell = wellPos-position  < 
	   Create a vector from the device position towards the gravity 
	   well's center. */
	wellPos[0] = 0;
	wellPos[1] = 0;
	wellPos[2] = 0;
	hduVecSubtract(positionTwell, wellPos, position);

	/* If the device position is within some distance of the gravity well's 
	   center, apply a spring force towards gravity well's center.  The force
	   calculation differs from a traditional gravitational body in that the
	   closer the device is to the center, the less force the well exerts;
	   the device behaves as if a spring were connected between itself and
	   the well's center. */
	if (hduVecMagnitude(positionTwell) < kGravityWellInfluence)
	{
		/* >  F = k * x  < 
		   F: Force in Newtons (N)
		   k: Stiffness of the well (N/mm)
		   x: Vector from the device endpoint position to the center 
		   of the well. */
		hduVecScale(force, positionTwell, kStiffness);
	}

	/* Send the force to the device. */
	hdSetDoublev(HD_CURRENT_FORCE, force);

	/* End haptics frame. */
	hdEndFrame(hHD);

	/* Check for errors and abort the callback if a scheduler error
	   is detected. */
	if (HD_DEVICE_ERROR(error = hdGetError()))
	{
		hduPrintError(stderr, &error, 
					  "Error detected while rendering gravity welln");

		if (hduIsSchedulerError(&error))
		{
			return HD_CALLBACK_DONE;
		}
	}

	/* Signify that the callback should continue running, i.e. that
	   it will be called again the next scheduler tick. */
	return HD_CALLBACK_CONTINUE;
}

Lastly, the setup method that establishes the callback:

HDSchedulerHandle hGravityWell = hdScheduleAsynchronous(gravityWellCallback, 0, HD_MAX_SCHEDULER_PRIORITY);