S K
S K

Reputation: 19

Unable to Subscribe to Odometry ROS Message Via Rosbridge

The aim is for my shape (ie. 'tracker') to emulate the movement of my robot. I have two files for this, one with the rosbridge code to pull the topics from the robot:

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

...and, in a separate file sourcing my rosbridge, this piece of code to move the shape in the front-end:

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

edit: I have included entirely the parts of my code relating to movement.

Upvotes: 0

Views: 868

Answers (2)

kaliatech
kaliatech

Reputation: 17867

I believe your problem is in this code:

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

The subscribe method will call the given callback, so returning OdomPosition from that doesn't really make sense. You could treat OdomPosition as a global variable, which I think is what you might have wanted to do originally. Something like:

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

Note that your current code recreates the object reference on every callback. However, even that has problems because there's no guarantee that the callback will happen before you call tracker.update in your moveTracker handling.

An alternative for what I think you really want to do, is to call tracker.update on every odom change. Perhaps something like this:

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

And then modify your tracker.update method declaration to take odomPosition as a parameter, and remove call to tracker.update in your moveTracker method.

Upvotes: 2

JWCS
JWCS

Reputation: 1201

Just to be clear, for the line which you note the error occurs, don't you mean to use the position argument you pass in? I'm assuming OdomPosition is not a variable in the scope outside of track()?

this.distanceX = position.xPos || 0;

Upvotes: 1

Related Questions