Esempio n. 1
0
double Line::distancePointToLine(Matrix<double> pos)
{
    double l = length();

    Matrix<double> eff_pos_a = effectivePosA();
    Matrix<double> eff_pos_b = effectivePosB();

    if (l <= 0)
    {
        return vecLength(pos - eff_pos_a);
    }

    const double t = vecDot(pos - eff_pos_a, eff_pos_b - eff_pos_a) / l; // This is readily shown by drawing out the relevant vectors

    if (t < 0.0)
    {
        return vecLength(pos - eff_pos_a);  // Beyond the 'eff_pos_a' end of the segment
    }
    else if (t > 1.0)
    {
        return vecLength(pos - eff_pos_b);  // Beyond the 'eff_pos_b' end of the segment
    }

    Matrix<double> projection = eff_pos_a + t * (eff_pos_b - eff_pos_a);  // Projection falls on the segment

    return vecLength(pos - projection);
}
void circlePlyAreaCT(Ball *inBall,LevelInfo *lvlInfo,float *padStepAng)
{
  vec2f P;
  vec2f center     = lvlInfo->center;
  int   counter    = 0;
  float vp, tan;
  float cx, cy;
  float lengthP;
  float radius     = lvlInfo->radius;
  float cRadLength = sqrtf((radius - inBall->ballRadius) * (radius - inBall->ballRadius));
  cx               = center.x;
  cy               = center.y;

  /* bound ball off the sides of circle play area */
  P.x = inBall->pos.x - cx;
  P.y = inBall->pos.y - cy;
  lengthP = vecLength(&P);

  if (lengthP >= cRadLength) {
    normalize (&P,1);
    tan = atan2(P.y,P.x) * 180/M_PI;
    /* if hit in the range of 210 to 310 deg, play loss 1 life */
    if (tan > -150.0 && tan < -30.0f) {
      lvlInfo->life += lvlInfo->life > 0 ? -1 : 5;
      inBall->pos.x = center.x;
      inBall->pos.y = center.y;
      inBall->ballVel.y = -1.4;
      inBall->ballVel.x = 0.0f;
      *padStepAng = 0.0f;
      return;
    }
    // Find projection
    vp = dotProduct(inBall->ballVel,P);

    inBall->ballVel.x -= 2 * vp * P.x;
    inBall->ballVel.y -= 2 * vp * P.y;
    normalize (&inBall->ballVel,2);

    P.x = cx - inBall->pos.x;
    P.y = cy - inBall->pos.y;
    lengthP = vecLength(&P);

    /* Move the ball out of wall */
    while (lengthP > sqrt ((radius - inBall->ballRadius) * (radius - inBall->ballRadius)))
    {
      counter++;
      inBall->pos.x += inBall->ballVel.x * 0.05;
      inBall->pos.y += inBall->ballVel.y * 0.05;
      P.x = cx - inBall->pos.x;
      P.y = cy - inBall->pos.y;
      lengthP = vecLength(&P);
      // Prevent infinite loops
      if (counter == 30)
        break;
    }
  }
}
Esempio n. 3
0
void AddrMem::convertType(ostream& os) const
{
    os << "(";

    os << PrecType::getName(prec());

    if (vecLength() > 1) os << vecLength();

    os << ")";
}
Esempio n. 4
0
void AddrMem::declareType(ostream& os) const
{
    os << _addrSpace.str();

    if (_isConst) os << "const ";

    os << PrecType::getName(prec());

    if (vecLength() > 1) os << vecLength();

    os << (_isPointer ? " * " : " ");
}
Esempio n. 5
0
void Particle::update(const std::vector< std::vector<sf::Vector2f> > &map) {
	// TODO: simplify, make faster
	if (vvel == sf::Vector2f(0, 0) || vecLength(vvel) < .00001f) {
		return;
	}

	sf::Time time_now = clock->getElapsedTime();
	if (lastUpdated.asMicroseconds() == 0) {
		// El primer frame del joc ningú es mou
		lastUpdated = time_now;
		return;
	}
	long long micros = time_now.asMicroseconds() - lastUpdated.asMicroseconds();
	sf::Vector2f a = vecUnit(vvel) * float(accel * micros);
	if (vecLength(a) < float(accel * micros)) {
		vvel = sf::Vector2f(0, 0);
		accel = 0;
		if (disappear) {
			alive = false;
		}
		return;
	} else {
		vvel += a;
	}

	target_movement = vvel * float(micros);

	lastUpdated = clock->getElapsedTime();

	prev_pos = position;
	position += target_movement;
	if (!between(position.x, -20000, 20000) || !between(position.y, -20000, 20000)) {
		alive = false;
		return;
	}
	if (collide) {
		for (auto &polygon : map) {
			// TODO: Try to call this less
			if (lineCrossesPoly(prev_pos, position, polygon)) {
				vvel = sf::Vector2f(0, 0);
				if (disappear) {
					alive = false;
				}
				return;
			}
		}
	}
}
Esempio n. 6
0
/* virtual */ SysStatusUval
FileLinuxDevZero::writev(const struct iovec *vec, uval vecCount,
			 ThreadWait **tw, GenState &moreAvail)
{
    moreAvail.state = FileLinux::READ_AVAIL | FileLinux::WRITE_AVAIL;
    return _SRETUVAL(vecLength(vec, vecCount));
}
Esempio n. 7
0
    /**
     * Adds a point for inside the sphere.
     * @param v point
     */
    void add(const Vec3f &v)
    {
        const float vMinusCenterLen = vecLength(v - m_center);

        if ( vMinusCenterLen > m_radius )
            m_radius = vMinusCenterLen;
    }
Esempio n. 8
0
/* virtual */ SysStatusUval
FileLinuxFile::writev(const struct iovec *vec, uval vecCount,
		      ThreadWait **tw, GenState &moreAvail)
{
    FLFDEBUG("writev");

    SysStatusUval rc;
    uval length_write;
    char* buf_write;
    uval length = vecLength(vec, vecCount);

    lock();
    moreAvail.state = FileLinux::READ_AVAIL|FileLinux::WRITE_AVAIL;

    rc = locked_writeAlloc(length, buf_write, tw);
    if (_FAILURE(rc)) {
	unLock();
	return rc;
    }
    length_write = _SGETUVAL(rc);
    if (length_write) {
	memcpy_fromiovec(buf_write, vec, vecCount, length_write);
	locked_writeFree(buf_write);
    }
    unLock();
    return rc;
}
Esempio n. 9
0
/* virtual */ SysStatusUval
FileLinuxFile::readv(struct iovec* vec, uval vecCount,
		     ThreadWait **tw, GenState &moreAvail)
{
    FLFDEBUG("readv");

    SysStatusUval rc;
    uval length_read;
    char* buf_read;
    uval length = vecLength(vec,vecCount);
    lock();
    moreAvail.state = FileLinux::READ_AVAIL|FileLinux::WRITE_AVAIL;
    rc = locked_readAlloc(length, buf_read, tw);
    if (_FAILURE(rc)) {
	unLock();
	//semantics shift from EOF error to 0 length on EOF
	if (_SCLSCD(rc) == FileLinux::EndOfFile) {
	    moreAvail.state = FileLinux::ENDOFFILE;
	    return 0;
	}
	return rc;
    }
    length_read = _SGETUVAL(rc);
    if (length_read) {
	memcpy_toiovec(vec, buf_read, vecCount, length_read);
	locked_readFree(buf_read);
    }
    unLock();
    return rc;
}
Esempio n. 10
0
void vecNormalize(Vec v)
{
	Flt len = vecLength(v);
	if (len == 0.0) {
		vecMake(0,0,1,v);
		return;
	}
	len = 1.0 / len;
	v[0] *= len;
	v[1] *= len;
	v[2] *= len;
}
Esempio n. 11
0
void updateAppendage(Scene* scene, int sceneIndex, cl_float3 p, cl_float3 q,
		cl_float3 w, float A, float B, int countA, int countB) {
	cl_float3 U;
	cl_float3 V;
	cl_float3 W;

	cl_float3 j;
	cl_float3 d;

	V = q;
	vecSub(V, p);

	float D = vecLength(V);
	float inverseD = 1.0f / D;
	vecScale(V, inverseD);

	W = w;
	vecNormalize(W);
	vecCross(U, V, W);

	float A2 = A*A;

	float y = 0.5f * inverseD * (A2 - B * B + D * D);
	double square = A2 - y*y;
	if (square < 0.0f)
		throw std::runtime_error("Unable to construct appendage");
	float x = sqrtf(square);

	j = p;
	vecScaledAdd(j, x, U);
	vecScaledAdd(j, y, V);

	d = j;
	vecSub(d, p);
	vecScale(d, 1.0f / float(countA));
	for (int i = 0; i <= countA; i++) {
		Sphere* sphere = &(scene->spheres[sceneIndex + i]);
		sphere->center = p;
		vecScaledAdd(sphere->center, float(i), d);
		vecScale(sphere->center, 0.1f);
	}

	d = j;
	vecSub(d, q);
	vecScale(d, 1.0f / float(countB));
	for (int i = 0; i <= countA; i++) {
		Sphere* sphere = &(scene->spheres[sceneIndex + i + countA + 1]);
		sphere->center = q;
		vecScaledAdd(sphere->center, float(i), d);
		vecScale(sphere->center, 0.1f);
	}
}
Esempio n. 12
0
 /**
  * Adds a sphere.    
  */
 void add(const BoundingSphere &sphere)
 {
     const float sCenterMinusCenterLen = vecLength(sphere.center() - m_center);
     if ( sCenterMinusCenterLen > m_radius )
     {
         m_center = (sphere.center() + m_center)/2.0f;
         m_radius = sCenterMinusCenterLen + hgMax(sphere.radius(), m_radius);
     }
     else if ( m_radius < sphere.radius() )
     {
         *this = sphere;
     }
 }
Esempio n. 13
0
void Line::alignWithVec(Matrix<double> vec)
{
    Matrix<double> new_vec = vecNormalize(vec)*vecLength(p_position_b-p_position_a);

    Matrix<double> middle(3, 1);
    middle[0] = p_position_a[0] + 0.5 * (p_position_b[0] - p_position_a[0]);
    middle[1] = p_position_a[1] + 0.5 * (p_position_b[1] - p_position_a[1]);
    middle[2] = p_position_a[2] + 0.5 * (p_position_b[2] - p_position_a[2]);

    p_position_a = middle - 0.5*new_vec;
    p_position_b = middle + 0.5*new_vec;

    computePrism();
    computeVertices();
}
Esempio n. 14
0
void setValues(fwPlane& _plane, const fwVec3d & _point1, const fwVec3d & _point2, const fwVec3d & _point3)
{
    SLM_TRACE_FUNC();
    fwVec3d  normalVec= cross(_point2 - _point1, _point3 -_point1);
    if((float)(vecLength(normalVec)) <= 0.0F) {
        normalVec[0] =0.0F;
        normalVec[1] =0.0F;
        normalVec[2] =1.0F;
    }
    normalize(normalVec);
    // Normal
    setNormal(_plane, normalVec);
    // Distance
    double distance = normalVec[0]*_point1[0] + normalVec[1]*_point1[1] + normalVec[2]*_point1[2];
    setDistance(_plane, distance);
}
Esempio n. 15
0
/* virtual */ SysStatusUval
FileLinuxVirtFile::readv(struct iovec* vec, uval vecCount,
			 ThreadWait **tw, GenState &moreAvail)
{
    /* FIXME: for now implementing only for vecCount == 1.
     * In this case it's not necessary to allocate a buffer for
     * performing the read operation and then invoke memcpy_toiovec
     */
    tassertMsg(vecCount == 1, "FileLinuxVirtFile:readv does not support "
	       "vecCount > 1 yet. See FIXME note.\n");
    SysStatusUval rc;
    uval length_read = 0, l, lr;
    uval length = vecLength(vec,vecCount);
    streamLock.acquire();
    moreAvail.state = FileLinux::READ_AVAIL|FileLinux::WRITE_AVAIL;

    char *buf_read = (char*) vec->iov_base;
    char *buf_cur_ptr = buf_read;

    while (length > 0) {
	l = length;
	if (l > MAX_IO_LOAD) {
	    l = MAX_IO_LOAD;
	}

	rc = stub._read(buf_cur_ptr, l);

	if (_FAILURE(rc)) {
	    //semantics shift from EOF error to 0 length on EOF
	    if (_SCLSCD(rc) == FileLinux::EndOfFile) {
		moreAvail.state = FileLinux::ENDOFFILE;
		rc = 0;
	    }
	    streamLock.release();
	    return rc;
	}

	lr = _SGETUVAL(rc);
	length_read += lr;
	buf_cur_ptr += lr;
	length -= lr;
	if (lr < l) break;    // got all there is to it
    }

    streamLock.release();
    return _SRETUVAL(length_read);
}
Esempio n. 16
0
/* virtual */ SysStatusUval
FileLinuxVirtFile::writev(const struct iovec *vec, uval vecCount,
			  ThreadWait **tw, GenState &moreAvail)
{
    /* FIXME: for now implementing only for vecCount == 1.
     * In this case it's not necessary to allocate a buffer for
     * performing the read operation and then invoke memcpy_toiovec
     */
    tassertMsg(vecCount == 1, "FileLinuxVirtFile:writev does not support "
	       "vecCount > 1 yet. See FIXME note.\n");

    SysStatusUval rc;
    uval length_written = 0, l, lw;
    char* buf_write = (char*) vec->iov_base;
    uval length = vecLength(vec, vecCount);

    streamLock.acquire();
    moreAvail.state = FileLinux::READ_AVAIL|FileLinux::WRITE_AVAIL;

    char *buf_cur_ptr = buf_write;

    while (length > 0) {
	l = length;
	if (l > MAX_IO_LOAD) {
	    l = MAX_IO_LOAD;
	}

	rc = stub._write(buf_cur_ptr, l);

	if (_FAILURE(rc)) {
	    streamLock.release();
	    return rc;
	}

	lw = _SGETUVAL(rc);
	length_written += lw;
	buf_cur_ptr += lw;
	length -= lw;
	if (lw < l) break;    // couldn't write all requested
    }

    streamLock.release();
    return _SRETUVAL(length_written);
}
Esempio n. 17
0
    bool sphereSphereCollision(const BoundingSphere &M,
                               const Vec3f &vel,
                               const BoundingSphere &S)
    {
        const Vec3f e = M.center() - S.center();
        const float r = S.radius() + M.radius();

        if ( vecLength(e) < r )
            return true;

        const float delta = Math::square(vecDot(e, vel))
            - vecDot(vel, vel) * (vecDot(e, e) - r*r);
        if ( delta < 0.0f )
            return false;

        const float t = (-vecDot(e, vel) - std::sqrt(delta)) / vecDot(vel, vel);
        if ( t < 0.0f || t > 1.0f )
            return false;

        return true;
    }
Esempio n. 18
0
/* virtual */ SysStatusUval
StreamServerConsole::sendto(struct iovec* vec, uval veclen, uval flags,
			    const char *addr, uval addrLen, 
			    GenState &moreAvail, 
			    void *controlData, uval controlDataLen,
			    __XHANDLE xhandle)
{
    uval len = vecLength(vec, veclen);
    char* buf = (char*)allocLocalStrict(len);

    tassertMsg((controlDataLen == 0), "oops\n");
    memcpy_fromiovec(buf, vec, veclen, len);

    SysConsole->write(buf, len);

    freeLocalStrict(buf, len);
    calcAvailable(moreAvail);

    if (XHANDLE_IDX(xhandle) != CObjGlobalsKern::ConsoleIndex) {
	clnt(xhandle)->setAvail(moreAvail);
    }

    return len;
}
Esempio n. 19
0
size_t Gathering::gatherSubscript(const size_t variableNumber,
                                  const size_t N,
                                  const bool xHasIndex,
                                  const bool yHasIndex,
                                  const size_t xOffset,
                                  const size_t yOffset)
{
    const AppSubscript appSub(N, xHasIndex, yHasIndex, xOffset, yOffset);

    if ( _appSubscript[variableNumber].count(appSub) )
    {
        return _appSubscript[ variableNumber ][ appSub ];
    }

    const size_t effVecLen = vecLength(variableNumber);

    const ArraySubscript arrSub(variableNumber,
                                N,
                                xHasIndex,
                                xOffset / effVecLen,
                                yHasIndex,
                                yOffset);

    if ( _subscriptToNumber.count(arrSub) )
    {
        return _appSubscript[ variableNumber ][ appSub ]
                   = _subscriptToNumber[ arrSub ];
    }

    _numberToSubscript[ _subscriptCounter ] = arrSub;
    _subscriptToNumber[ arrSub ] = _subscriptCounter;

    _appSubscript[ variableNumber ][ appSub ] = _subscriptCounter;

    return _subscriptCounter++;
}
Esempio n. 20
0
// vecNormalize - Returns a unit vector in the same direction.
// Result can be the same vector as the vector argument.
void vecNormalize(geomVec v, geomVec result)
{
  double norm = vecLength(v);
  result[0] = v[0]/norm;
  result[1] = v[1]/norm;
}
void applyTransitions(jrPlanet *pPlanet) {
	if (pPlanet) {
		float afForce[4];
		vecInitDVec(afForce);

		for (jrPlanet *pOtherPlanet = g_pHead; pOtherPlanet; pOtherPlanet = pOtherPlanet->m_pNext) {

			if (pPlanet != pOtherPlanet && pOtherPlanet)  {
				float afDistance[3];
				vecSub(pPlanet->afPosition, pOtherPlanet->afPosition, afDistance); //get distance

				float fForce = g_fGravity * (pPlanet->fMass * pOtherPlanet->fMass) / (vecLength(afDistance));

				float afNormaliseInput[4];
				vecSub(pOtherPlanet->afPosition, pPlanet->afPosition, afNormaliseInput);
				float afNormaliseOutput[4];
				vecInit(afNormaliseOutput);

				vecNormalise(afNormaliseInput, afNormaliseOutput);

				afForce[0] = (afForce[0] + afNormaliseOutput[0]);
				afForce[1] = (afForce[1] + afNormaliseOutput[1]);
				afForce[2] = (afForce[2] + afNormaliseOutput[2]);

				if (pPlanet->fMass > pOtherPlanet->fMass) {
					if (detectCollision(pPlanet, pOtherPlanet, afDistance)) {
						break;
					}
				}
			}
		}

		// calc accV -> afForce/mass
		pPlanet->afAcceleration[0] = afForce[0] / pPlanet->fMass;
		pPlanet->afAcceleration[1] = afForce[1] / pPlanet->fMass;
		pPlanet->afAcceleration[2] = afForce[2] / pPlanet->fMass;

		// calc new pos
		if (!pPlanet->m_bFixed) {
			pPlanet->afPosition[0] = pPlanet->afPosition[0] + (pPlanet->afVelocity[0] * g_fVelocityMultiplier);
			pPlanet->afPosition[1] = pPlanet->afPosition[1] + (pPlanet->afVelocity[1] * g_fVelocityMultiplier);
			pPlanet->afPosition[2] = pPlanet->afPosition[2] + (pPlanet->afVelocity[2] * g_fVelocityMultiplier);
		}
		// calc new vel
		pPlanet->afVelocity[0] = pPlanet->afVelocity[0] + pPlanet->afAcceleration[0];
		pPlanet->afVelocity[1] = pPlanet->afVelocity[1] + pPlanet->afAcceleration[1];
		pPlanet->afVelocity[2] = pPlanet->afVelocity[2] + pPlanet->afAcceleration[2];

		// apply drag
		pPlanet->afAcceleration[0] = pPlanet->afAcceleration[0] * g_fDamping;
		pPlanet->afAcceleration[1] = pPlanet->afAcceleration[1] * g_fDamping;
		pPlanet->afAcceleration[2] = pPlanet->afAcceleration[2] * g_fDamping;

		// end

		if (pPlanet->iHistoryCount < g_iHistoryVariableLength - 4) {
			pPlanet->iHistoryCount = pPlanet->iHistoryCount + 3;
		}
		else {
			pPlanet->iHistoryCount = 0;
		}

		pPlanet->afPositionHistory[pPlanet->iHistoryCount] = pPlanet->afPosition[0];
		pPlanet->afPositionHistory[pPlanet->iHistoryCount + 1] = pPlanet->afPosition[1];
		pPlanet->afPositionHistory[pPlanet->iHistoryCount + 2] = pPlanet->afPosition[2];

		if (pPlanet->fRotationAngle > 359.0f) {
			pPlanet->fRotationAngle = 0.0f;
		}
		else {
			pPlanet->fRotationAngle = pPlanet->fRotationAngle += 1.0f;
		}
	}

}
Esempio n. 22
0
inline Vec4f vecNormal(const Vec4f &v) {
  const float len = 1.0f/vecLength(v);
  return Vec4f(v[0] * len, v[1] * len, v[2] * len, v[3] * len);
}
Esempio n. 23
0
File: imu.c Progetto: jonkster/biot
myQuat_t getPosition(mpu9250_t dev)
{
    imuData_t imuData;
    if (getIMUData(dev, &imuData))
    {
        if (! validIMUData(imuData))
        {
            puts("invalid IMU data");
            if (failureCount++ > 20)
            {
                puts("Error in IMU, restarting!");
                identifyYourself("IMU failure");
                if (! initialiseIMU(&dev))
                {
                    puts("Could not initialise IMU! dying...");
                    exit(1);
                }
            }
            return currentQ;
        }
        failureCount = 0;

        /************************************************************************
         * Get Gyro data that records current angular velocity and create an
         * estimated quaternion representation of orientation using this
         * velocity, the time interval between the last calculation and the
         * previous orientation:
         * change in position = velocity * time,
         * new position = old position + change in position)
         ************************************************************************/

        // get orientation as deduced by adding gyro measured rotational
        // velocity (times time interval) to previous orientation.
        double gx1 = (double)(imuData.gyro.x_axis);
        double gy1 = (double)(imuData.gyro.y_axis);
        double gz1 = (double)(imuData.gyro.z_axis);
        double omega[3] = { gx1, gy1, gz1 }; // this will be in degrees/sec
        //double omegaMagnitude = fabs(vecLength(omega));

        uint32_t dt = imuData.ts - lastIMUData.ts; // dt in microseconds
        lastIMUData = imuData;
        myQuat_t gRot = makeQuatFromAngularVelocityTime(omega, dt/1000000.0);
        myQuat_t gyroDeducedQ =  quatMultiply(currentQ, gRot);
        quatNormalise(&gyroDeducedQ);
        if (! useGyroscopes)
        {
            makeIdentityQuat(&gyroDeducedQ);
        }

        if (! (useAccelerometers | useMagnetometers))
        {
            // return now with just the gyro data
            currentQ = gyroDeducedQ;
            lastIMUData = imuData;
            return currentQ;
        }

        // get orientation from the gyro as Roll Pitch Yaw (ie Euler angles)
        double gyroDeducedYPR[3];
        quatToEuler(gyroDeducedQ, gyroDeducedYPR);
        double currentYPR[3];
        quatToEuler(currentQ, currentYPR);


        // Calculate a roll/pich/yaw from the accelerometers and magnetometers.

        /************************************************************************
         * Get Accelerometer data that records gravity direction and create a
         * 'measured' Quaternion representation of orientation (will only be
         * pitch and roll, not yaw)
         ************************************************************************/

        // get gravity direction from accelerometer
        double ax1 = imuData.accel.x_axis / 1024.0;
        double ay1 = imuData.accel.y_axis / 1024.0;
        double az1 = imuData.accel.z_axis / 1024.0;
        double downSensor[3] = { ax1, ay1, az1 };
        if (fabs(vecLength(downSensor) - 0.98) > 0.5)
        {
            // excessive accelerometer reading, bail out
            //printf("too much accel: %f ", fabs(vecLength(downSensor)));
            //dumpVec(downSensor);
            currentQ = gyroDeducedQ;
            lastIMUData = imuData;
            return currentQ;
        }
        vecNormalise(downSensor);

        // The accelerometers can only measure pitch and roll (in the world reference
        // frame), calculate the pitch and roll values to account for
        // accelerometer readings, make yaw = 0.

        double ypr[3];
        double downX = downSensor[X_AXIS];
        double downY = downSensor[Y_AXIS];
        double downZ = downSensor[Z_AXIS];

        // add a little X into Z when calculating roll to compensate for
        // situations when pitching near vertical as Y, Z will be near 0 and
        // the results will be unstable
        double fiddledDownZ = sqrt(downZ*downZ + 0.001*downX*downX);
        if (downZ <= 0) // compensate for loss of sign when squaring Z
            fiddledDownZ *= -1.0;
        ypr[ROLL] = atan2(downY, fiddledDownZ);
        ypr[PITCH] = -atan2(downX, sqrt(downY*downY + downZ*downZ));
        ypr[YAW] = 0;  // yaw == 0, accelerometer cannot measure yaw
        if (! useAccelerometers) 
        {
            // if no accelerometers, use roll and pitch values from gyroscope
            // derived orientation
            ypr[PITCH] = gyroDeducedYPR[PITCH];
            ypr[ROLL] = gyroDeducedYPR[ROLL];
            ypr[YAW] = gyroDeducedYPR[YAW];
        }
        else if (vecLength(downSensor) == 0)
        {
            puts("weightless?");
            // something wrong! - weightless??
            ypr[PITCH] = gyroDeducedYPR[PITCH];
            ypr[ROLL] = gyroDeducedYPR[ROLL];
            ypr[YAW] = gyroDeducedYPR[YAW];
        }

        if (! useMagnetometers)
        {
            ypr[YAW] = gyroDeducedYPR[YAW];
        }
        myQuat_t accelQ = eulerToQuat(ypr);
        myQuat_t invAccelQ = quatConjugate(accelQ);


        /************************************************************************
         * Get Magnetometer data that records north direction and create a
         * 'measured' Quaternion representation of orientation (will only be
         * yaw)
         ************************************************************************/

        // get magnetometer indication of North
        double mx1 = (double)(imuData.mag.x_axis - magHardCorrection[X_AXIS]);
        double my1 = (double)(imuData.mag.y_axis - magHardCorrection[Y_AXIS]);
        double mz1 = (double)(imuData.mag.z_axis - magHardCorrection[Z_AXIS]);
        mx1 *= magSoftCorrection[X_AXIS];
        my1 *= magSoftCorrection[Y_AXIS];
        mz1 *= magSoftCorrection[Z_AXIS];
        // NB MPU9250 has different XYZ axis for magnetometers than for gyros
        // and accelerometers so juggle x,y,z here...
        double magV[3] = { my1, mx1, -mz1 };
        vecNormalise(magV);
        // make quaternion representing mag readings
        myQuat_t magQ = quatFromValues(0, magV[X_AXIS], magV[Y_AXIS], magV[Z_AXIS]);
        if (vecLength(magV) == 0)
        {
            // something wrong! - no magnetic field??
            //puts("not on earth?");
            magQ = quatFromValues(1, 0, 0, 0);
        }

        // the magnetometers can only measure yaw (in the world reference
        // frame), adjust the yaw of the roll/pitch/yaw values calculated
        // earlier to account for the magnetometer readings.
        if (useMagnetometers) 
        {
            // pitch and roll the mag direction using accelerometer info to
            // create a quaternion that represents the IMU as if it was
            // horizontal (so we can get pure yaw)
            myQuat_t horizQ = quatMultiply(accelQ, magQ);
            horizQ = quatMultiply(horizQ, invAccelQ);

            // calculate pure yaw
            ypr[YAW] = -atan2(horizQ.y, horizQ.x);
        }

        // measuredQ is the orientation as measured using the
        // accelerometer/magnetometer readings
        myQuat_t measuredQ = eulerToQuat(ypr);
        // check measured and deduced orientations are not wildly different (eg
        // due to a 360d alias flip) and adjust if problem...
        measuredQ = adjustForCongruence(measuredQ, gyroDeducedQ);

        /*************************************************************************
         * The gyro estimated orientation will be smooth and precise over short
         * time intervals but small errors will accumulate causing it to
         * drift over time.  The 'measured' orientation as obtained from the
         * magnetometer and accelerometer will be jumpy but will always average
         * around the correct orientation.
         *
         * Take the mag and accel 'measured' orientation and the gyro
         * 'estimated' orientation and create a new 'current' orientation that
         * is the estimated orientation corrected slightly towards the measured
         * orientation.  That way we get the smooth precision of the gyros but
         * eliminate the accumulation of drift errors.
         ************************************************************************/

        if (useGyroscopes)
        {
            // the new orientation is the gyro deduced position corrected
            // towards the accel/mag measured position using interpolation
            // between quaternions.
            currentQ = slerp(gyroDeducedQ, measuredQ, 0.02);
        }
        else
        {
            currentQ = measuredQ;
        }

        if (! isQuatValid(currentQ))
        {
            puts("error in quaternion, reseting orientation...");
            displayData(imuData);
            dumpQuat(currentQ);
            makeIdentityQuat(&currentQ);
        }
    }
    return currentQ;
}
Esempio n. 24
0
// Virtual functions
void Vector2Test::Run( std::ostream & p_Trace )
{
	std::cout << "-------------------------------------------" << std::endl;
	std::cout << "Starting Vector2 test." << std::endl;

	// Run a constuctor test for the different types
	Bit::Vector2i8 veci8( 1, 2 );
	Bit::Vector2u8 vecu8( 1, 2 );
	Bit::Vector2i16 veci16( 1, 2 );
	Bit::Vector2u16 vecu16( 1, 2 );
	Bit::Vector2i32 veci32( 1, 2 );
	Bit::Vector2u32 vecu32( 1, 2 );
	Bit::Vector2i64 veci64( 1, 2 );
	Bit::Vector2u64 vecu64( 1, 2 );
	Bit::Vector2f32 vecf32( 1.0f, 2.0f );
	Bit::Vector2f64 vecf64( 1.0f, 2.0f );

	// Assert the vectors
	TestAssert( veci8.x == 1 && veci8.y == 2 );
	TestAssert( vecu8.x == 1 && vecu8.y == 2 );
	TestAssert( veci16.x == 1 && veci16.y == 2 );
	TestAssert( vecu16.x == 1 && vecu16.y == 2 );
	TestAssert( veci32.x == 1 && veci32.y == 2 );
	TestAssert( vecu32.x == 1 && vecu32.y == 2 );
	TestAssert( veci64.x == 1 && veci64.y == 2 );
	TestAssert( vecu64.x == 1 && vecu64.y == 2 );
	TestAssert( vecf32.x == 1.0f && vecf32.y == 2.0f );
	TestAssert( vecf64.x == 1.0f && vecf64.y == 2.0f );

	// Casting tests
	Bit::Vector2f64 vecCast1( vecf32 );
	Bit::Vector2f32 vecCast2( vecf64 );
	TestAssert( vecCast1.x == vecf32.x && vecCast1.y == vecf32.y);
	TestAssert( vecCast2.x == vecf64.x && vecCast2.y == vecf64.y);

	// Assert Magnitude function
	Bit::Vector2f32 vecLength( 100.0f, 0.0f );
	TestAssert( vecLength.Length( ) == 100.0f );

	// Assert normal function
	Bit::Vector2f32 vecNormal1 = Bit::Vector2f32( 123.0f, 0.0f ).Normal( );
	TestAssert( vecNormal1.x == 1.0f && vecNormal1.y == 0.0f );

	// Assert normalize function
	Bit::Vector2f32 vecNormal2( 123.0f, 0.0f );
	vecNormal2.Normalize( );
	TestAssert( vecNormal2.x == 1.0f && vecNormal2.y == 0.0f );
	
	// Assert dot product function
	TestAssert( Bit::Vector2f32( -1.0f, 0.0f ).Dot( Bit::Vector2f32( 1.0f, 0.0f ) ) == -1.0f );
	TestAssert( Bit::Vector2f32( 0.0f, 1.0f ).Dot( Bit::Vector2f32( 1.0f, 0.0f ) ) == 0.0f );
	TestAssert( Bit::Vector2f32( 1.0f, 0.0f ).Dot( Bit::Vector2f32( 1.0f, 0.0f ) ) == 1.0f );

	// Assert angle between vectors function
	Bit::Vector2f32 vecAngle1( -1.0f, 0.0f );
	Bit::Vector2f32 vecAngle2( 0.0f, 1.0f );
	TestAssert( Bit::Math::EqualEpsilonHalf<Bit::Float64>( Bit::Vector2f32::AngleBetweenVectors( vecAngle1, vecAngle2 ).AsDegrees( ), 90.0f ) );

	// Assert the absolute function
	Bit::Vector2f32 vecAbs1 = Bit::Vector2f32( -1.0f, -2.0f ).Absolute( );
	Bit::Vector2f32 vecAbs2 = Bit::Vector2f32( 1.0f, -2.0f ).Absolute( );
	Bit::Vector2f32 vecAbs3 = Bit::Vector2f32( -1.0f, 2.0f ).Absolute( );
	Bit::Vector2f32 vecAbs4 = Bit::Vector2f32( 1.0f, 2.0f ).Absolute( );
	TestAssert( vecAbs1.x == 1.0f && vecAbs1.y == 2.0f );
	TestAssert( vecAbs2.x == 1.0f && vecAbs2.y == 2.0f );
	TestAssert( vecAbs3.x == 1.0f && vecAbs3.y == 2.0f );
	TestAssert( vecAbs4.x == 1.0f && vecAbs4.y == 2.0f );

	// Assert the rotate function
	Bit::Vector2f32 vecRotate( 0.0f, 1.0f );
	vecRotate.Rotate( Bit::Degrees( 90.0f ) );
	TestAssert( Bit::Math::EqualEpsilonHalf<Bit::Float64>( vecRotate.x, -1.0f ) &&
				Bit::Math::EqualEpsilonHalf<Bit::Float64>( vecRotate.y, 0.0f ) );
	
	
	// Print the finish text
	std::cout << "Finished Vector2 Test." << std::endl;
	std::cout << "-------------------------------------------" << std::endl;
}
Esempio n. 25
0
  /**
   * Adds a sphere.
   */
  void Add(const BoundingSphere &sphere) {
    const float centers_dist = vecLength(m_center - sphere.get_center());

    m_center = (sphere.get_center() + m_center)*0.5f;
    m_radius = centers_dist*0.5f + std::max(m_radius, sphere.get_radius());
  }
Esempio n. 26
0
double Line::length() const
{
    return vecLength(p_position_a - p_position_b) + p_offset_a + p_offset_b;
}