合并 3 个订阅数据以加入新对象 rxjs 中的数据 angular 9
merge 3 subscription data to join the data in new object rxjs angular 9
我需要一些帮助来将来自 3 个不同传感器的数据合并到一个对象中,我正在使用一些 cordova 插件来获取 acc gyr 和 mag 数据,但我无法解决的问题是订阅所有 3 个可观察对象同时将数据放在同一个对象中,我尝试递归调用可观察对象但它不起作用,这是我的函数:
startGyroscope(){
this.gyroscopeSerie = [];
this.subscriptionGyro = this.gyr.watch({frequency : 75}).subscribe(
(magnetometer: any) => {
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0
};
data.x = magnetometer.x;
data.y = magnetometer.y;
data.z = magnetometer.z;
data.timestamp = + new Date(),
this.gyroscopeSerie.push(data);
}
);
}
startMagnetometer(){
this.magnometerSerie = [];
this.subscriptionMag = this.mag.watchReadings().subscribe(
(magnetometer: any) => {
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0,
magnitude: 0
};
data.x = magnetometer.x;
data.y = magnetometer.y;
data.z = magnetometer.z;
data.timestamp = + new Date(),
data. magnitude = magnetometer.magnitude
this.magnometerSerie.push(data);
}
);
}
startAccelerometer(){
this.accelerometerSerie = [];
const frequency = 75;
this.watchID = setInterval(() =>{
this.watchAcceleration().then((accelerometer: any) =>{
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0,
roll: 0,
pitch: 0,
yaw: 0
};
data.x = accelerometer.x;
data.y = accelerometer.y;
data.z = accelerometer.z;
data.roll = accelerometer.roll;
data.pitch = accelerometer.pitch;
data.yaw = accelerometer.yaw;
data.timestamp = accelerometer.timestamp;
this.accelerometerSerie.push(data);
});
},frequency);
}
// this plugin doesnt have an wrapper so i had to create a promise callback
watchAcceleration(){
return new Promise((resolveCallback, rejectCallback) =>{
new Promise((resolve, reject) =>{
navigator.accelerometer.watchAcceleration(resolve,reject,{frequency : 75});
}).then((acceleration) => {
resolveCallback(acceleration);
}).catch((error) =>{
rejectCallback(error);
});
});
}
此对象中所有值的预期输出:
{ magx: 0 , magy: 0, magz: 0, accx: 0, accy: 0, accz: 0, roll: 0, pitch: 0, yaw: 0, girx: 0, giry: 0, girz: 0, timestamp: 0 };
提前致谢
如果我对你的理解正确的话,这些 observable 中的每一个都以大致相同的间隔发出,并且应该大致相同。在所有三个 observable 都发出新值并组合之后,您只想拥有新的组合对象。为此,我会像这样混合组合 latest 和 distinctUntilChanged。 (请原谅打字错误,因为这是在我的 phone 上完成的)
gyrData: Observable <any>
magData: Observable <any>
accelData = new Subject<any>();
combined: Observable<any
combinedSub;
initCombinedData() {
this.startGyroscope();
this. startMagnetometer();
this.startAccelerometer();
this.combined = combineLatest([
this.gyrData,
this.magData,
this.accelData
])
.pipe(
distinctUntilChanged((a, b) =>
// emit only when all time stamps have update to avoid any lag in updates and ensure they stay in sync
a[0].timestamp === b[0].timestamp ||
a[1].timestamp === b[1].timestamp ||
a[2].timestamp === b[2].timestamp ||
),
map(([gyr, mag, acc]) => {
const latestTime = Math.max(
gyr.timestamp,
mag.timestamp,
acc.timestamp)
return { magx: mag.x, magy: mag.y, magz: mag.z, accx: acc.x, accy: acc.y, accz: acc.z, roll: acc.roll, pitch: acc.pitch, yaw: acc.yaw, girx: gyr.x, giry: gyr.y, girz: gyr.z, timestamp: new Date(latestTime) };
})
)
this.combinedSub = this.combined.subscribe();
}
startGyroscope(){
this.gyrData = this.gyr.watch({frequency : 75})
.pipe(
map((magnetometer: any) => {
const data = {
x: magnetometer.x,
z: magnetometer.z,
y: magnetometer.y,
timestamp: + new Date()
};
return data;
})
}
startMagnetometer(){
this.magData = this.mag.watchReadings()
.pipe(
map((m: any) => {
const data = {
x: m.x,
z: m.z,
y: m.y,
timestamp: + new Date(),
magnitude: m. magnitude
};
return data;
}
);
}
startAccelerometer(){
const frequency = 75;
this.watchID = setInterval(() =>{
this.watchAcceleration()
.then((a: any) =>{
const data = {
x: a.x,
z: a.z,
y: a.y,
timestamp: a.timestamp,
roll: a.roll,
pitch: a.pitch
yaw: a.yaw,
};
this.accelData.next(data);
});
},frequency);
}
watchAcceleration(){
return new Promise((resolveCallback, rejectCallback) =>{
new Promise((resolve, reject) =>{
navigator.accelerometer
.watchAcceleration(resolve,reject, {frequency : 75});
}).then((acceleration) => {
resolveCallback(acceleration);
}).catch((error) =>{
rejectCallback(error);
});
});
}
我需要一些帮助来将来自 3 个不同传感器的数据合并到一个对象中,我正在使用一些 cordova 插件来获取 acc gyr 和 mag 数据,但我无法解决的问题是订阅所有 3 个可观察对象同时将数据放在同一个对象中,我尝试递归调用可观察对象但它不起作用,这是我的函数:
startGyroscope(){
this.gyroscopeSerie = [];
this.subscriptionGyro = this.gyr.watch({frequency : 75}).subscribe(
(magnetometer: any) => {
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0
};
data.x = magnetometer.x;
data.y = magnetometer.y;
data.z = magnetometer.z;
data.timestamp = + new Date(),
this.gyroscopeSerie.push(data);
}
);
}
startMagnetometer(){
this.magnometerSerie = [];
this.subscriptionMag = this.mag.watchReadings().subscribe(
(magnetometer: any) => {
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0,
magnitude: 0
};
data.x = magnetometer.x;
data.y = magnetometer.y;
data.z = magnetometer.z;
data.timestamp = + new Date(),
data. magnitude = magnetometer.magnitude
this.magnometerSerie.push(data);
}
);
}
startAccelerometer(){
this.accelerometerSerie = [];
const frequency = 75;
this.watchID = setInterval(() =>{
this.watchAcceleration().then((accelerometer: any) =>{
let data = {
x: 0,
z: 0,
y: 0,
timestamp: 0,
roll: 0,
pitch: 0,
yaw: 0
};
data.x = accelerometer.x;
data.y = accelerometer.y;
data.z = accelerometer.z;
data.roll = accelerometer.roll;
data.pitch = accelerometer.pitch;
data.yaw = accelerometer.yaw;
data.timestamp = accelerometer.timestamp;
this.accelerometerSerie.push(data);
});
},frequency);
}
// this plugin doesnt have an wrapper so i had to create a promise callback
watchAcceleration(){
return new Promise((resolveCallback, rejectCallback) =>{
new Promise((resolve, reject) =>{
navigator.accelerometer.watchAcceleration(resolve,reject,{frequency : 75});
}).then((acceleration) => {
resolveCallback(acceleration);
}).catch((error) =>{
rejectCallback(error);
});
});
}
此对象中所有值的预期输出:
{ magx: 0 , magy: 0, magz: 0, accx: 0, accy: 0, accz: 0, roll: 0, pitch: 0, yaw: 0, girx: 0, giry: 0, girz: 0, timestamp: 0 };
提前致谢
如果我对你的理解正确的话,这些 observable 中的每一个都以大致相同的间隔发出,并且应该大致相同。在所有三个 observable 都发出新值并组合之后,您只想拥有新的组合对象。为此,我会像这样混合组合 latest 和 distinctUntilChanged。 (请原谅打字错误,因为这是在我的 phone 上完成的)
gyrData: Observable <any>
magData: Observable <any>
accelData = new Subject<any>();
combined: Observable<any
combinedSub;
initCombinedData() {
this.startGyroscope();
this. startMagnetometer();
this.startAccelerometer();
this.combined = combineLatest([
this.gyrData,
this.magData,
this.accelData
])
.pipe(
distinctUntilChanged((a, b) =>
// emit only when all time stamps have update to avoid any lag in updates and ensure they stay in sync
a[0].timestamp === b[0].timestamp ||
a[1].timestamp === b[1].timestamp ||
a[2].timestamp === b[2].timestamp ||
),
map(([gyr, mag, acc]) => {
const latestTime = Math.max(
gyr.timestamp,
mag.timestamp,
acc.timestamp)
return { magx: mag.x, magy: mag.y, magz: mag.z, accx: acc.x, accy: acc.y, accz: acc.z, roll: acc.roll, pitch: acc.pitch, yaw: acc.yaw, girx: gyr.x, giry: gyr.y, girz: gyr.z, timestamp: new Date(latestTime) };
})
)
this.combinedSub = this.combined.subscribe();
}
startGyroscope(){
this.gyrData = this.gyr.watch({frequency : 75})
.pipe(
map((magnetometer: any) => {
const data = {
x: magnetometer.x,
z: magnetometer.z,
y: magnetometer.y,
timestamp: + new Date()
};
return data;
})
}
startMagnetometer(){
this.magData = this.mag.watchReadings()
.pipe(
map((m: any) => {
const data = {
x: m.x,
z: m.z,
y: m.y,
timestamp: + new Date(),
magnitude: m. magnitude
};
return data;
}
);
}
startAccelerometer(){
const frequency = 75;
this.watchID = setInterval(() =>{
this.watchAcceleration()
.then((a: any) =>{
const data = {
x: a.x,
z: a.z,
y: a.y,
timestamp: a.timestamp,
roll: a.roll,
pitch: a.pitch
yaw: a.yaw,
};
this.accelData.next(data);
});
},frequency);
}
watchAcceleration(){
return new Promise((resolveCallback, rejectCallback) =>{
new Promise((resolve, reject) =>{
navigator.accelerometer
.watchAcceleration(resolve,reject, {frequency : 75});
}).then((acceleration) => {
resolveCallback(acceleration);
}).catch((error) =>{
rejectCallback(error);
});
});
}