📄 motion.c
字号:
// 0 - check GPS speed (kph) // 1 - check GPS distance (meters) // 2 - check OBC speed (kph) - if available UInt16 defStartType = (UInt16)propGetUInt32(PROP_MOTION_START_TYPE, 0); double defMotionStart = propGetDouble(PROP_MOTION_START, 0.0); // kph/meters /* speed */ double speedKPH = 0.0; if (newFix) { speedKPH = newFix->speedKPH; } /* check motion start/stop */ // - send start/stop/in-motion event // PROP_GPS_MIN_SPEED should already be accounted for UInt32 nowTime = utcGetTimeSec(); utBool isCurrentlyMoving = utFalse; if (defMotionStart > 0.0) { // kph/meters /* check for first GPS motion fix */ if (!gpsIsValid(&lastMotionFix)) { // first GPS fix gpsCopy(&lastMotionFix, newFix); } /* check for currently moving */ if (defStartType == MOTION_START_GPS_METERS) { // GPS distance // check GPS distance (meters) if (gpsIsValid(newFix) && gpsIsValid(&lastMotionFix)) { // validate double deltaMeters = gpsMetersToPoint(&(newFix->point), &(lastMotionFix.point)); if (deltaMeters >= defMotionStart) { isCurrentlyMoving = utTrue; } } } else if (speedKPH >= defMotionStart) { // (speedKPH > 0.0) isCurrentlyMoving = utTrue; } /* check for currently moving */ if (isCurrentlyMoving) { // I am moving lastStoppedTimer = (TimerSec_t)0L; // reset stopped time gpsClear(&lastStoppedFix); // we're moving, clear this fix gpsCopy(&lastMotionFix, newFix); // save new motion fix if (!isInMotion) { // I wasn't moving before, but now I am isInMotion = utTrue; lastInMotionMessageTimer = utcGetTimer(); // start "in-motion" timer // send 'start' event _queueMotionEvent(MOTION_START_PRIORITY, STATUS_MOTION_START, nowTime, newFix); } else { // continued in-motion } } else { // I'm not moving if (isInMotion) { // I was moving before, but now I'm not. if (lastStoppedTimer <= 0L) { // start "stopped" timer (first non-moving sample) lastStoppedTimer = utcGetTimer(); gpsCopy(&lastStoppedFix, newFix); // first event at 'stop' // this will be reset again if we start moving before the time expires } // Check to see if my 'stop' timer has expired UInt16 defMotionStop = (UInt16)propGetUInt32(PROP_MOTION_STOP,0L); // seconds utBool officiallyStopped = utcIsTimerExpired(lastStoppedTimer,defMotionStop); // Note: also check for other 'stop' indicators here (ie. ignition off) if (officiallyStopped) { // time expired, we are now officially NOT moving gpsCopy(&lastMotionFix, newFix); // save new motion fix _motionStop(nowTime, newFix); } else { // I've not yet officially 'stopped' (I may be at a stop sign/light) } } else { // still not moving } } } else { // this is necessary in case "start/stop" events were turned off while moving isInMotion = utFalse; // default definition for motion (may not be used by all clients) isCurrentlyMoving = (speedKPH >= 2.0)? utTrue : utFalse; } /* check in-motion/dormant */ // - send "in-motion" events while moving (between start/stop events) // - send "dormant" events while not moving if (isInMotion) { // moving (between start/stop) ['isCurrentlyMoving' may be false] UInt32 defMotionInterval = propGetUInt32(PROP_MOTION_IN_MOTION, 0L); if (defMotionInterval > 0L) { // In-motion interval has been defined - we want in-motion events. if ((defMotionInterval < MIN_IN_MOTION_INTERVAL) && !isDebugMode()) { // in-motion interval is too small, reset to minimum value defMotionInterval = MIN_IN_MOTION_INTERVAL; //propSetUInt32(PROP_MOTION_IN_MOTION, defMotionInterval); } UInt16 defStopType = (UInt16)propGetUInt32(PROP_MOTION_STOP_TYPE, 0); // 0=after_delay, 1=when_stopped if ((defStopType == MOTION_STOP_WHEN_STOPPED) && !isCurrentlyMoving) { // 'defStopType' indicates that in-motion messages are to be generated iff actually moving, // and we are NOT currently moving. Thus we suspend in-motion events. } else if (utcIsTimerExpired(lastInMotionMessageTimer,defMotionInterval)) { // we're moving, and the in-motion interval has expired lastInMotionMessageTimer = utcGetTimer(); // send an in-motion message _queueMotionEvent(IN_MOTION_PRIORITY, STATUS_MOTION_IN_MOTION, nowTime, newFix); } else { // we are considered moving, but the in-motion interval has not expired } } lastDormantMessageTimer = (TimerSec_t)0L; dormantCount = 0L; } else { // if (defMotionStart > 0.0) <-- this would check dormant only if not tracking start/stop // we're not moving (or we're not tracking start/stop), check dormant // Note: if tracking start/stop is off (ie. PROP_MOTION_START is '0'), then // 'dormant' checking will be in effect. To turn off dormant checking as // well, PROP_MOTION_DORMANT_INTRVL must also be set to '0'. // check dormant interval UInt32 defDormantInterval = propGetUInt32(PROP_MOTION_DORMANT_INTRVL, 0L); if (defDormantInterval > 0L) { if ((defDormantInterval < MIN_DORMANT_INTERVAL) & !isDebugMode()) { defDormantInterval = MIN_DORMANT_INTERVAL; //propSetUInt32(PROP_MOTION_DORMANT_INTRVL, defDormantInterval); } UInt32 maxDormantCount = propGetUInt32(PROP_MOTION_DORMANT_COUNT, 0L); if ((maxDormantCount <= 0L) || (dormantCount < maxDormantCount)) { if (lastDormantMessageTimer <= 0L) { // initialize dormant timer lastDormantMessageTimer = utcGetTimer(); dormantCount = 0L; } else if (utcIsTimerExpired(lastDormantMessageTimer,defDormantInterval)) { lastDormantMessageTimer = utcGetTimer(); // send dormant message _queueMotionEvent(DORMANT_PRIORITY, STATUS_MOTION_DORMANT, nowTime, newFix); dormantCount++; } } } } /* check excessive speed */ double defMaxSpeedKPH = propGetDouble(PROP_MOTION_EXCESS_SPEED, 0.0); // kph if (defMaxSpeedKPH > 0.0) { // maxSpeed is defined utBool isCurrentlyExceedingSpeed = (speedKPH >= defMaxSpeedKPH)? utTrue : utFalse; if (isCurrentlyExceedingSpeed) { // I'm currently exceeding maxSpeed if (!isExceedingSpeed) { // I wasn't exceeding maxSpeed before, but now I am isExceedingSpeed = utTrue; _queueMotionEvent(EXCESS_SPEED_PRIORITY, STATUS_MOTION_EXCESS_SPEED, nowTime, newFix); } else { // I'm still exceeding maxSpeed } } else { // I'm currently not exceeding maxSpeed if (isExceedingSpeed) { // I was exceeding maxSpeed before, but now I'm not double speedSetbackKPH = (defMaxSpeedKPH > EXCESS_SPEED_SETBACK)? (defMaxSpeedKPH - EXCESS_SPEED_SETBACK) : defMaxSpeedKPH; if (speedKPH < speedSetbackKPH) { // I've slowed down enough to reset the excess-speed flag isExceedingSpeed = utFalse; } else { // not quite slow enough to reset the excess-speed flag } } else { // I'm still not exceeding maxSpeed } } } else { // this is necessary in case "speeding" events were turned off while speeding if (isExceedingSpeed) { isExceedingSpeed = utFalse; } }#if defined(TRANSPORT_MEDIA_SERIAL) || defined(SECONDARY_SERIAL_TRANSPORT)// enable for Bluetooth transport only /* simple moving check */ if (isCurrentlyMoving) { // we're moving, check interval UInt32 movingInterval = propGetUInt32(PROP_MOTION_MOVING_INTRVL,0L); if (movingInterval > 0L) { if (utcIsTimerExpired(lastMovingMessageTimer,movingInterval)) { // moving timer expired lastMovingMessageTimer = utcGetTimer(); _queueMotionEvent(MOVING_PRIORITY, STATUS_MOTION_MOVING, nowTime, newFix); } } }#endif}/* check new GPS fix for various motion events */void motionCheckGPS(const GPS_t *oldFix, const GPS_t *newFix){ MOTION_LOCK { _motionCheckGPS(oldFix, newFix); } MOTION_UNLOCK}// ----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -