【问题标题】:Node.js kalman filter 1DNode.js 卡尔曼滤波器 1D
【发布时间】:2019-02-21 22:28:01
【问题描述】:

首先,您好,我正在使用 Ibeacon 研究关于内部定位的 node.js javascript。作为我工作的助手:我使用 Evothings Studio。我正在将我的代码传输到 Evothings 工作室并通过我的 android 和 ios 手机查看我的作品。现在我想告诉你我遇到的问题。根据RSSI信号级别,我发现距离在计算中不是很准确。我想用卡尔曼滤波器来清除这个信号电平(RSSI)的噪声。本文介绍了 Javascript 中卡尔曼滤波器的使用。据说很容易实现,但我无法开始练习。 “” 卡尔曼滤波器库:“https://github.com/wouterbulten/kalmanjs”。如何使用此卡尔曼滤波器清除 RSSI 信号中的噪声?如何将卡尔曼滤波器应用于这些代码?

var app = (function()
{
	// Application object.
	var app = {};

	// History of enter/exit events.
	var mRegionEvents = [];

	// Nearest ranged beacon.
	var mNearestBeacon = null;

	// Timer that displays nearby beacons.
	var mNearestBeaconDisplayTimer = null;

	// Background flag.
	var mAppInBackground = false;

	// Background notification id counter.
	var mNotificationId = 0;

	// Mapping of region event state names.
	// These are used in the event display string.
	var mRegionStateNames =
	{
		'CLRegionStateInside': 'Enter',
		'CLRegionStateOutside': 'Exit'
	};

	// Here monitored regions are defined.
	// TODO: Update with uuid/major/minor for your beacons.
	// You can add as many beacons as you want to use.
	var mRegions =
	[
		{
			id: 'BEACON1',
			uuid: 'fda50693-a4e2-4fb1-afcf-c6eb07647825',
			major: 10035,
			minor: 56498
		},
		{
			id: 'region2',
			uuid: 'f7826da6-4fa2-4e98-8024-bc5b71e0893e',
			major: 60378,
			minor: 22122
		}
	];

	// Region data is defined here. Mapping used is from
	// region id to a string. You can adapt this to your
	// own needs, and add other data to be displayed.
	// TODO: Update with major/minor for your own beacons.
	var mRegionData =
	{
		'BEACON1': 'WGX_BEACON1',
		'region2': 'Region Two'
	};

	app.initialize = function()
	{
		document.addEventListener('deviceready', onDeviceReady, false);
		document.addEventListener('pause', onAppToBackground, false);
		document.addEventListener('resume', onAppToForeground, false);
	};

	function onDeviceReady()
	{
		startMonitoringAndRanging();
		startNearestBeaconDisplayTimer();
		displayRegionEvents();
	}

	function onAppToBackground()
	{
		mAppInBackground = true;
		stopNearestBeaconDisplayTimer();
	}

	function onAppToForeground()
	{
		mAppInBackground = false;
		startNearestBeaconDisplayTimer();
		displayRegionEvents();
	}

	function startNearestBeaconDisplayTimer()
	{
		mNearestBeaconDisplayTimer = setInterval(displayNearestBeacon, 1000);
	}

	function stopNearestBeaconDisplayTimer()
	{
		clearInterval(mNearestBeaconDisplayTimer);
		mNearestBeaconDisplayTimer = null;
	}

	function startMonitoringAndRanging()
	{
		function onDidDetermineStateForRegion(result)
		{
			saveRegionEvent(result.state, result.region.identifier);
			displayRecentRegionEvent();
		}

		function onDidRangeBeaconsInRegion(result)
		{
			updateNearestBeacon(result.beacons);
		}

		function onError(errorMessage)
		{
			console.log('Monitoring beacons did fail: ' + errorMessage);
		}

		// Request permission from user to access location info.
		cordova.plugins.locationManager.requestAlwaysAuthorization();

		// Create delegate object that holds beacon callback functions.
		var delegate = new cordova.plugins.locationManager.Delegate();
		cordova.plugins.locationManager.setDelegate(delegate);

		// Set delegate functions.
		delegate.didDetermineStateForRegion = onDidDetermineStateForRegion;
		delegate.didRangeBeaconsInRegion = onDidRangeBeaconsInRegion;

		// Start monitoring and ranging beacons.
		startMonitoringAndRangingRegions(mRegions, onError);
	}

	function startMonitoringAndRangingRegions(regions, errorCallback)
	{
		// Start monitoring and ranging regions.
		for (var i in regions)
		{
			startMonitoringAndRangingRegion(regions[i], errorCallback);
		}
	}

	function startMonitoringAndRangingRegion(region, errorCallback)
	{
		// Create a region object.
		var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(
			region.id,
			region.uuid,
			region.major,
			region.minor);

		// Start ranging.
		cordova.plugins.locationManager.startRangingBeaconsInRegion(beaconRegion)
			.fail(errorCallback)
			.done();

		// Start monitoring.
		cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion)
			.fail(errorCallback)
			.done();
	}

	function saveRegionEvent(eventType, regionId)
	{
		// Save event.
		mRegionEvents.push(
		{
			type: eventType,
			time: getTimeNow(),
			regionId: regionId
		});

		// Truncate if more than ten entries.
		if (mRegionEvents.length > 10)
		{
			mRegionEvents.shift();
		}
	}

	function getBeaconId(beacon)
	{
		return beacon.uuid + ':' + beacon.major + ':' + beacon.minor;
	}

	function isSameBeacon(beacon1, beacon2)
	{
		return getBeaconId(beacon1) == getBeaconId(beacon2);
	}

	function isNearerThan(beacon1, beacon2)
	{
		return beacon1.accuracy > 0
			&& beacon2.accuracy > 0
			&& beacon1.accuracy < beacon2.accuracy;
	}

	function updateNearestBeacon(beacons)
	{
		for (var i = 0; i < beacons.length; ++i)
		{
			var beacon = beacons[i];
			if (!mNearestBeacon)
			{
				mNearestBeacon = beacon;
			}
			else
			{
				if (isSameBeacon(beacon, mNearestBeacon) ||
					isNearerThan(beacon, mNearestBeacon))
				{
					mNearestBeacon = beacon;
				}
			}
		}
	}

	function displayNearestBeacon()
	{
		if (!mNearestBeacon) { return; }

		// Clear element.
		$('#beacon').empty();

		// Update element.
		var element = $(
			'<li>'
			+	'<strong>BEACON1</strong><br />'
			+	'UUID: ' + mNearestBeacon.uuid + '<br />'
			+	'Major: ' + mNearestBeacon.major + '<br />'
			+	'Minor: ' + mNearestBeacon.minor + '<br />'
			+	'Distance: ' + mNearestBeacon.accuracy + '<br />'
			+	'RSSI: ' + mNearestBeacon.rssi + '<br />'
			+ '</li>'
			);
		$('#beacon').append(element);
	}

	function displayRecentRegionEvent()
	{
		if (mAppInBackground)
		{
			// Set notification title.
			var event = mRegionEvents[mRegionEvents.length - 1];
			if (!event) { return; }
			var title = getEventDisplayString(event);

			// Create notification.
			cordova.plugins.notification.local.schedule({
    			id: ++mNotificationId,
    			title: title });
		}
		else
		{
			displayRegionEvents();
		}
	}

	function displayRegionEvents()
	{
		// Clear list.
		$('#events').empty();

		// Update list.
		for (var i = mRegionEvents.length - 1; i >= 0; --i)
		{
			var event = mRegionEvents[i];
			var title = getEventDisplayString(event);
			var element = $(
				'<li>'
				+ '<strong>' + title + '</strong>'
				+ '</li>'
				);
			$('#events').append(element);
		}

		// If the list is empty display a help text.
		if (mRegionEvents.length <= 0)
		{
			var element = $(
				'<li>'
				+ '<strong>'
				+	'İbeacon Taramasi Yapiliyor.'
				+ '</strong>'
				+ '</li>'
				);
			$('#events').append(element);
		}
	}

	function getEventDisplayString(event)
	{
		return event.time + ': '
			+ mRegionStateNames[event.type] + ' '
			+ mRegionData[event.regionId];
	}

	function getTimeNow()
	{
		function pad(n)
		{
			return (n < 10) ? '0' + n : n;
		}

		function format(h, m, s)
		{
			return pad(h) + ':' + pad(m)  + ':' + pad(s);
		}

		var d = new Date();
		return format(d.getHours(), d.getMinutes(), d.getSeconds());
	}

	return app;

})();

app.initialize();

【问题讨论】:

  • 恕我直言,如果您可以将示例代码缩减为几行来展示您的问题,您更有可能得到答案。我们是这里的志愿者,很难浏览大量代码。请edit您的问题。
  • 是的,我理解你,但我已将我的代码的位置添加到卡尔曼过滤器中,因为我不知道我的代码在哪里。所以我想告诉你的是:我不知道我的代码中的卡尔曼滤波器是什么。这就是我分享整件事的原因。
  • 我同意 O. Jones 的观点。这里有很多与问题无关的代码,例如onAppToBackground。 “我不知道我的代码在哪里”是什么意思?
  • @david-knipe 是我分享所有代码的唯一原因,因为我不知道在哪里实现卡尔曼滤波器。
  • "github.com/wouterbulten/kalmanjs" 从这里开始,我想将 RSS 过滤器应用于您的卡尔曼过滤器。

标签: javascript node.js ibeacon kalman-filter rssi


【解决方案1】:

在您完成对卡尔曼滤波器的试验后,您可能会发现距离估计中的误差仍然太高。这是因为除了 RSSI 测量中的随机噪声之外的其他误差源,其中许多可能是影响接收器测量的无线电信号电平的其他变量(例如反射、障碍、天线方向图变化)的函数。

一般来说,使用基于 RSSI 的直接距离计算,在 1 米的真实距离处最多可以准确估计 0.5-2 米,而在更远的距离处准确度要低得多。即使在使用卡尔曼滤波器或运行平均值滤除噪声后也是如此。 (请注意,iOS 距离估计使用 20 秒的 RSSI 运行平均值,而 CLBeacon 上的 RSSI 字段值是 1 秒内的平均值。)

如果使用三边测量或类似的方法来计算位置,你会发现你只能在不超过 1-2 米的非常短的距离内得到可行的结果。

【讨论】:

  • 是的,我知道这一点,但是如果我在我的项目中应用卡尔曼滤波器应用,据说距离估计的准确性会增加。 “wouterbulten.nl/blog/tech/…”在这里。你能给我一些关于如何将卡尔曼滤波器应用于我的共享代码的信息吗?
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 2021-05-06
相关资源
最近更新 更多