0
点赞
收藏
分享

微信扫一扫

【PX4仿真】使用PX4+Gazebo+MAVROS+ROS进行无人机仿真中提高IMU消息频率的方法

npm拉下来最新的2.3.9版本,发现一些原来Js代码已经不能用了。顺便解读了下最新定义的内容

// <reference types="node" />

export const VERSIONS: {
    V1_0: string;
    V1_1: string;
    V1_2: string;
    supportedVersions: () => string[];
};

export class Client {
    connected: boolean;
    counter: number;
    heartbeat: {
        incoming: number;
        outgoing: number;
    };
    maxWebSocketFrameSize: number;
    subscriptions: {};
    ws: WebSocket;

    debug(...args: string[]): any;

    connect(
        headers: { login: string; passcode: string; host?: string | undefined }, // 头部
        connectCallback: (frame?: Frame) => any, // 返回消息的监听器,从服务器收消息
        errorCallback?: (error: Frame | string) => any, // 错误信息的监听器
    ): any;
    connect(headers: {}, connectCallback: (frame?: Frame) => any, errorCallback?: (error: Frame | string) => any): any;
    connect(
        login: string,
        passcode: string,
        connectCallback: (frame?: Frame) => any,
        errorCallback?: (error: Frame | string) => any,
        host?: string,
    ): any;
    disconnect(disconnectCallback: () => any, headers?: {}): any; // 拆连接

    send(destination: string, headers?: {}, body?: string): any;
    subscribe(destination: string, callback?: (message: Message) => any, headers?: {}): Subscription;
    unsubscribe(id: string): void;

    begin(transaction: string): any;
    commit(transaction: string): any;
    abort(transaction: string): any;

    ack(messageID: string, subscription: string, headers?: {}): any;
    nack(messageID: string, subscription: string, headers?: {}): any;
}

export interface Subscription {
    id: string;
    unsubscribe(): void;
}

export interface Message extends Frame {
    ack(headers?: {}): any;
    nack(headers?: {}): any;
}

export class Frame {
    command: string;
    headers: {};
    body: string;
    constructor(command: string, headers?: {}, body?: string);

    toString(): string;
    static sizeOfUTF8(s: string): number;
    static unmarshall(datas: any): any;
    static marshall(command: string, headers?: {}, body?: string): any;
}

export function client(url: string, protocols?: string | string[]): Client;
export function over(ws: WebSocket): Client;
export function overTCP(host: string, port: number): Client;
export function overWS(url: string): Client;
export function setInterval(interval: number, f: (...args: any[]) => void): NodeJS.Timer;
export function clearInterval(id: NodeJS.Timer): void;

ChatGPT
typescript
Copy code
/// <reference types="node" />

// 定义了支持的 STOMP 协议版本
export const VERSIONS: {
    V1_0: string;
    V1_1: string;
    V1_2: string;
    supportedVersions: () => string[];
};

// 定义了 STOMP 客户端类
export class Client {
    connected: boolean; // 标识客户端是否连接
    counter: number; // 消息计数器
    heartbeat: { // 心跳配置
        incoming: number; // 接收心跳频率
        outgoing: number; // 发送心跳频率
    };
    maxWebSocketFrameSize: number; // WebSocket 最大消息帧大小
    subscriptions: {}; // 订阅列表
    ws: WebSocket; // WebSocket 连接

    // 调试日志函数
    debug(...args: string[]): any;

    // 连接到 STOMP 服务器的方法,支持多种重载形式
    connect(
        headers: { login: string; passcode: string; host?: string | undefined }, // 连接头信息
        connectCallback: (frame?: Frame) => any, // 连接成功的回调函数
        errorCallback?: (error: Frame | string) => any, // 连接错误的回调函数
    ): any;
    connect(headers: {}, connectCallback: (frame?: Frame) => any, errorCallback?: (error: Frame | string) => any): any;
    connect(
        login: string,
        passcode: string,
        connectCallback: (frame?: Frame) => any,
        errorCallback?: (error: Frame | string) => any,
        host?: string,
    ): any;

    // 断开与 STOMP 服务器的连接
    disconnect(disconnectCallback: () => any, headers?: {}): any;

    // 发送消息到指定目的地
    send(destination: string, headers?: {}, body?: string): any;

    // 订阅指定目的地的消息
    subscribe(destination: string, callback?: (message: Message) => any, headers?: {}): Subscription;

    // 取消订阅
    unsubscribe(id: string): void;

    // 开启事务
    begin(transaction: string): any;

    // 提交事务
    commit(transaction: string): any;

    // 回滚事务
    abort(transaction: string): any;

    // 手动确认消息
    ack(messageID: string, subscription: string, headers?: {}): any;

    // 手动否认消息
    nack(messageID: string, subscription: string, headers?: {}): any;
}

// 订阅对象接口
export interface Subscription {
    id: string; // 订阅 ID
    unsubscribe(): void; // 取消订阅方法
}

// 消息对象接口,扩展自 Frame
export interface Message extends Frame {
    ack(headers?: {}): any; // 手动确认消息方法
    nack(headers?: {}): any; // 手动否认消息方法
}

// STOMP 帧对象类
export class Frame {
    command: string; // 帧命令
    headers: {}; // 帧头部
    body: string; // 帧主体
    constructor(command: string, headers?: {}, body?: string); // 构造函数

    // 将帧对象转换为字符串
    toString(): string;

    // 计算 UTF-8 编码字符串的大小
    static sizeOfUTF8(s: string): number;

    // 反序列化 STOMP 帧
    static unmarshall(datas: any): any;

    // 序列化 STOMP 帧
    static marshall(command: string, headers?: {}, body?: string): any;
}

// 创建 STOMP 客户端的辅助函数
export function client(url: string, protocols?: string | string[]): Client;

// 使用现有的 WebSocket 连接创建 STOMP 客户端的辅助函数
export function over(ws: WebSocket): Client;

// 使用 TCP 连接创建 STOMP 客户端的辅助函数
export function overTCP(host: string, port: number): Client;

// 使用 WebSocket 连接地址创建 STOMP 客户端的辅助函数
export function overWS(url: string): Client;

// 发送客户端心跳
export function setInterval(interval: number, f: (...args: any[]) => void): NodeJS.Timer;

// 取消发送客户端心跳
export function clearInterval(id: NodeJS.Timer): void;

然后写一段简短的代码:

<script lang="ts" setup>
import { ref, inject, onMounted, onBeforeUnmount, defineProps, watch } from 'vue'
import Stomp from 'stompjs'

const MQTT_SERVICE = 'ws://localhost:15674/ws' // mq服务地址

const MQTT_USERNAME = 'user' // mq连接用户名

const MQTT_PASSWORD = '123456' // mq连接密码

function connectMQ() {
  const socket = new WebSocket(MQTT_SERVICE)

  const stompClient = Stomp.over(socket)

  stompClient.heartbeat.outgoing = 0

  stompClient.heartbeat.incoming = 0

  const onConnected = () => {
    console.log('登录成功!')
    stompClient.subscribe('a11022a6-ad17-459e-8b23-1ca6599af4f9', onMessageReceived) // 订阅需要的队列
  }

  const onMessageReceived = (message: { body: any }) => {
    console.log('返回数据:', message.body)
  }

  const onError = (error: any) => {
    console.error('RabbitMQ连接失败,错误原因:', error)
    console.error('5秒后重新连接......')
    window.setTimeout(() => {
      connectMQ()
    }, 5000)
  }
  stompClient.connect(MQTT_USERNAME, MQTT_PASSWORD, onConnected, onError, '/')
}

onMounted(() => {
  connectMQ()
})
</script>

然后去rabbitmq管理器给队列发个点对点消息:


试了下,能收到消息


但是出现一个问题,连接质量似乎不怎么好啊,老是掉线:

dashboard.vue:33 RabbitMQ连接失败,错误原因: Whoops! Lost connection to ws://localhost:15674/ws

看来连接质量不怎么好啊,加上个心跳,每15s跳一次:
前面代码关闭了下推,我们加上个上报看看,默认是10s一次,前面都设置为0了:
By default, stomp.js defines a heartbeat of 10000,10000 (to send and receive heartbeats every 10 seconds).

<script lang="ts" setup>
import { ref, inject, onMounted, onUnmounted, defineProps, watch } from 'vue'
import Stomp from 'stompjs'

const MQTT_SERVICE = 'ws://localhost:15674/ws' // mq服务地址

const MQTT_USERNAME = 'user' // mq连接用户名

const MQTT_PASSWORD = '123456' // mq连接密码

let heartbeat: NodeJS.Timer | undefined = undefined

function connectMQ() {
  const socket = new WebSocket(MQTT_SERVICE)

  const stompClient = Stomp.over(socket)

  stompClient.heartbeat.outgoing = 15000

  stompClient.heartbeat.incoming = 0

  const onConnected = () => {
    console.log('登录成功!')
    stompClient.subscribe('a11022a6-ad17-459e-8b23-1ca6599af4f9', onMessageReceived)
  }

  const onMessageReceived = (message: { body: any }) => {
    console.log('返回数据:', message.body)
  }

  const onError = (error: any) => {
    console.error('RabbitMQ连接失败,错误原因:', error)
    console.error('5秒后重新连接......')
    window.setTimeout(() => {
      connectMQ()
    }, 5000)
  }
  stompClient.connect(MQTT_USERNAME, MQTT_PASSWORD, onConnected, onError, '/')
  heartbeat = Stomp.setInterval(15000, () => {
    console.log('心跳呀')
  })
}

onMounted(() => {
  connectMQ()
})

onUnmounted(() => {
  if (heartbeat) {
    Stomp.clearInterval(heartbeat)
  }
})
</script>

这下稳定多了:

正式代码可以考虑把接收的消息数据和方法都放到vuex的store里

举报

相关推荐

0 条评论