无法通过 Rosbridge 订阅 Odometry ROS 消息

Unable to Subscribe to Odometry ROS Message Via Rosbridge

目的是让我的形状(即。'tracker')模仿我的机器人的运动。我为此准备了两个文件,其中一个包含从机器人中提取主题的 rosbridge 代码:

listener_Odom = new ROSLIB.Topic ({
    ros : ros,
    name : '/odom',
    messageType : 'nav_msgs/Odometry'
});

let odomPosition = {xPos : 0, yPos : 0};
listener_Odom.subscribe('/odom', function(message){
    console.log(`Received message on ${listener_Odom.name} : ${message.data}`);

   let odomPosition = {
        xPos : message.pose.pose.position.x,
        yPos : message.pose.pose.position.y
    } 

    tracker.update(odomPosition);

...并且,在我的 rosbridge 的一个单独文件中,这段代码用于在前端移动形状:

tracker = new track(30, 50, "white", 100, 820, 0)
function track(width, height, color, distanceX, distanceY, rotation, odomPosition){ 
    this.width = width;
    this.height = height;
    this.speed = 0;
    //this.distanceX = odomPosition.xPos || 0;
    //this.distanceY = odomPosition.yPos || 0;
    this.rotation = rotation || 0;
    this.rotationSpeed = 0;
    console.log("inside track()");

    this.update = function(odomPosition){
        ctx = mainCanvas.ctx1;
        ctx.fillStyle = color;
        ctx.save();
        ctx.translate(odomPosition.xPos, odomPosition.yPos);
        ctx.rotate(this.rotation); //rotate diagram specified below:
        ctx.fillRect(-this.width/2, -this.height/2, width, height); //first 2 variables ensure that it rotates around its center, and not around origin
        ctx.beginPath();
        ctx.moveTo(50, 0);
        ctx.lineTo(10,25);
        ctx.lineTo(10,-25);
        ctx.fill();
        ctx.restore();
    }
    this.newPosition = function(){
        this.rotation += this.rotationSpeed;
        this.distanceX += this.speed * Math.cos(this.rotation); //twist with respect to cosine and sine; 
        this.distanceY += this.speed * Math.sin(this.rotation);
    }
}

function moveTracker(){ //recognize keys from keyboard
    mainCanvas.clear();
    tracker.speed = 0; //for linear speed
    tracker.rotationSpeed = 0; //for angular speed
    if (mainCanvas.key && mainCanvas.key == 37) { //left key; countercl. rotation
        tracker.rotationSpeed = -.1/ (Math.PI);
        rosCmdVel.publish(rosTwistLft);
        //console.log('swinging anticlockwise');
    }
    if (mainCanvas.key && mainCanvas.key == 38) { //up key
        tracker.speed = 3;
        rosCmdVel.publish(rosTwistFwd);
        //console.log('moving forward');
    }
    if (mainCanvas.key && mainCanvas.key == 39) { //right key; clockw. rotation
        tracker.rotationSpeed = .1 / (Math.PI);
        rosCmdVel.publish(rosTwistRht);
        //console.log('swinging clockwise');
     }
    if (mainCanvas.key && mainCanvas.key == 40) { //down key
        tracker.speed= -3;
        rosCmdVel.publish(rosTwistBwd);
        //console.log('moving backward');
    }
    tracker.newPosition();
    //tracker.update();
}

编辑:我已经完全包含了我的代码中与运动相关的部分。

需要说明的是,对于您注意到错误发生的那一行,您不是要使用您传入的 position 参数吗?我假设 OdomPosition 不是 track()?

范围之外的变量
this.distanceX = position.xPos || 0;

我认为您的问题出在这段代码中:

listener_Odom.subscribe('/odom', function(message){
    console.log(`Received message on ${listener_Odom.name} : ${message.data}`);
    OdomPosition = {
        xPos : message.pose.pose.position.x,
        yPos : message.pose.pose.position.y
    } 
    return OdomPosition;
   }
); // minor: I think this line is missing in your pasted code

subscribe 方法将调用给定的回调,因此从中返回 OdomPosition 没有任何意义。您可以将 OdomPosition 视为全局变量,我认为这是您最初可能想要做的。类似于:

let OdomPosition = {xPos:0, yPos:0}
listener_Odom.subscribe('/odom', function(message){
      console.log(`Received message on ${listener_Odom.name} : ${message.data}`);
      OdomPosition.xPos : message.pose.pose.position.x
      OdomPosition.yPos : message.pose.pose.position.y
    }
); 

请注意,您当前的代码会在每次回调时重新创建对象引用。然而,即使那样也有问题,因为不能保证回调会在 你在 moveTracker 处理中调用 tracker.update 之前发生。

认为 你真正想做的事情的替代方法是在每次 odom 更改时调用 tracker.update。也许是这样的:

listener_Odom.subscribe('/odom', function(message){
    console.log(`Received message on ${listener_Odom.name} : ${message.data}`);
    let odomPosition = {
        xPos : message.pose.pose.position.x,
        yPos : message.pose.pose.position.y
    } 

    tracker.update(odomPosition)
  }
); 

然后修改您的 tracker.update 方法声明以将 odomPosition 作为参数,并在您的 moveTracker 方法中删除对 tracker.update 的调用。