无法通过Rosbridge订阅Odometry ROS消息

时间:2019-07-29 15:50:50

标签: javascript json ros motion

目标是使我的形状(即“跟踪器”)模仿我的机器人的运动。为此,我有两个文件,一个文件带有罗斯桥代码,用于从机器人提取主题:

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);

...,然后在一个单独的文件中找到我的罗斯桥,这段代码在前端移动形状:

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();
}
  • 如何使我的前端文件正确订阅/ odom 主题并移动形状?

编辑:我已经完全将代码中与运动有关的部分包括在内。

2 个答案:

答案 0 :(得分:2)

我相信您的问题出在此代码中:

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之前 会发生回调。

您真正想做的另一种选择是,在每次更改时都调用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的调用。

答案 1 :(得分:1)

请明确说明,对于您注意到错误发生的行,您不是要使用传入的position自变量吗?我假设OdomPosition不是track()之外的范围内的变量?

this.distanceX = position.xPos || 0;