【发布时间】:2019-03-31 12:31:32
【问题描述】:
所以我下面有两个服务和一个组件。
这是ros.service.ts,它与我的服务器建立连接
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RosService {
// Creates object with the ROS library
// @ts-ignore <= Makes ts happy, wont error
ros = new ROSLIB.Ros({
// Set listen URL for ROS communication
url : 'ws://localhost:9090'
});
initialize() {
let data;
// Listens for error from ROS and logs it
this.ros.on('error', function(error) {
console.log(error);
});
// Find out exactly when we made a connection.
this.ros.on('connection', function() {
console.log('Connection made!');
});
// Logs when connection is closed
this.ros.on('close', function() {
console.log('Connection closed.');
});
}
}
// Data is gotten through subscription from each node service
// this.driveControlService.getDriveControlData().subscribe(msg => {
// this.data = msg;
// console.log(msg);
// });
// }
接下来,这是从服务器的子集(或节点,对于那些有 ROS 经验的人)调用的服务 ms5837.service.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import '../../assets/roslib.js';
@Injectable({
providedIn: 'root'
})
export class Ms5837Service {
// Creates object with the ROS library
// @ts-ignore <= Makes ts happy, wont error
ros = new ROSLIB.Ros({
// Set listen URL for ROS communication
url : 'ws://localhost:9090'
});
// Define subject to hold data values
ms5837: BehaviorSubject<any> = new BehaviorSubject(1);
// Initializer to be called every time BMP280 is going to be used
initialize() {
// Get Data from ROS bmp280 Topic
// @ts-ignore
const ms5837Listener = new ROSLIB.Topic({
ros: this.ros,
name: '/rov/ms5837',
messageType: 'ms5837/ms5837_data'
});
// Subscribe to bmpListener
ms5837Listener.subscribe((message) => {
console.log('Recieved Message on ' + ms5837Listener.name + ' : ' + message);
// console.log(message);
this.ms5837.next(message);
});
}
// Define data getter
getData(): Observable<any> {
if (this.ms5837) {
return this.ms5837.asObservable();
}
}
}
最后,我正在尝试获取此组件中的数据并将其分配给数据以在图表中使用。 telemetrydata.component.ts
import {OnInit, Component, AfterViewInit} from '@angular/core';
import { Chart } from 'chart.js';
import { Ms5837Service } from '../../../services/ms5837.service';
import { Ms5837Data } from '../../../services/data-models/ms5837.model';
@Component({
selector: 'app-depth-chart',
templateUrl: './depth-chart.component.html',
styleUrls: ['./depth-chart.component.css']
})
export class DepthChartComponent implements OnInit {
exteriorAltitude = [0];
seconds = [0];
name = 'Depth Chart';
type = 'line';
data = {
labels: this.seconds,
datasets: [{
label: 'Depth',
data: this.exteriorAltitude,
backgroundColor: [
'rgba(0,188,212, .3)'
],
borderColor: [
'#00bcd4'
],
borderWidth: 1
}]
};
options = {
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
};
constructor(private ms5837Service: Ms5837Service) {}
ngOnInit() {
this.ms5837Service.initialize();
this.ms5837Service.getData().subscribe((msg: Ms5837Data) => {
if (msg !== undefined) {
console.log(msg);
this.exteriorAltitude.push(msg.altitudeM);
console.log(this.exteriorAltitude);
this.seconds.push(msg.header.stamp.secs);
}
});
}
}
目前,与服务器建立连接需要一点时间,因此通过 observable 传递给 telemetrydata.component.ts 的第一个值是未定义的,这会导致崩溃。我尝试过使用 async 和 promise,但坦率地说,我对 rxjs 还不够熟练,还没有做到这一点。任何帮助将不胜感激。
【问题讨论】:
-
第一个值不是未定义的。它是 1:BehaviorSubect 的初始值。第二个,即使它是未定义的,也不应该使任何事情失败,因为如果 msg 未定义,您什么也不做。请解释实际发生的情况,并发布所有相关日志和错误消息以及堆栈跟踪。另外,我看不出第一类有什么意义,因为它没有在任何地方使用。
-
@JBNizet 第一个服务需要建立连接。我忘了补充说它是在我的 App Module onInit 中调用的。我会尽快添加日志。
-
我对 ROS 一无所知,但我怀疑它是否需要。它所做的只是与第二个相同,加上注册回调以在连接建立或关闭或出现错误时得到通知。