Reputation: 19
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
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
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