how to get wheel encoder count from turtlebot's /odom topic - ros
turtlebot's odom topic gives:
header: seq: 406289 stamp:
secs: 4392
nsecs: 160000000 frame_id: odom child_frame_id: base_footprint pose: pose:
position:
x: 1.56701645246e-05
y: -9.82132735628e-06
z: 0.0
orientation:
x: 0.0
y: 0.0
z: -0.548275342929
w: 0.836297882537 covariance: [0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.05] twist: twist:
linear:
x: -2.67171244095e-06
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -0.000185729678152 covariance: [0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
I'd like to find the wheel encoder count from this data. How does turtlebot use wheel encoder values to compute positions? Where can I find the code that does this?
Related
WebGL got weird drawing(loop not closed) with gl.TRIANGLES [closed]
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers. This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers. Closed 2 years ago. Improve this question I am trying to use gl.TRIANGLES to draw an "I" shape, I have meshed it in 24 triangles, the first 22 gives me this shape, however, whenever I added the last two triangle vertices, I got this weird shape, I double-checked the coordinates of the last two triangles, and they are correct, so not sure what could be wrong in my code, which I pasted it here. shape "I" with 22 triangles weird shape "I" with 24 triangles /** * #file A simple WebGL example drawing a triangle with colors * #author Eric Shaffer <shaffer1#eillinois.edu> */ /** #global The WebGL context */ var gl; /** #global The HTML5 canvas we draw on */ var canvas; /** #global A simple GLSL shader program */ var shaderProgram; /** #global The WebGL buffer holding the triangle */ var vertexPositionBuffer; /** #global The WebGL buffer holding the vertex colors */ var vertexColorBuffer; /** * Creates a context for WebGL * #param {element} canvas WebGL canvas * #return {Object} WebGL context */ function createGLContext(canvas) { var context = null; context = canvas.getContext("webgl2"); if (context) { context.viewportWidth = canvas.width; context.viewportHeight = canvas.height; } else { alert("Failed to create WebGL context!"); } return context; } /** * Loads Shaders * #param {string} id ID string for shader to load. Either vertex shader/fragment shader */ function loadShaderFromDOM(id) { var shaderScript = document.getElementById(id); // If we don't find an element with the specified id // we do an early exit if (!shaderScript) { return null; } var shaderSource = shaderScript.text; var shader; if (shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if (shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } gl.shaderSource(shader, shaderSource); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } /** * Setup the fragment and vertex shaders */ function setupShaders() { vertexShader = loadShaderFromDOM("shader-vs"); fragmentShader = loadShaderFromDOM("shader-fs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Failed to setup shaders"); } gl.useProgram(shaderProgram); shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); } /** * Populate buffers with data */ function setupBuffers() { vertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); var triangleVertices = [ /*triangle*/ -0.7, -1.0, 0.0, -0.6, -0.9, 0.0, 0.7, -1.0, 0.0, /*triangle*/ -0.6, -0.9, 0.0, 0.7, -1.0, 0.0, 0.6, -0.9, 0.0, /*triangle*/ 0.7, -1.0, 0.0, 0.7, -0.5, 0.0, 0.6, -0.6, 0.0, /*triangle*/ 0.6, -0.9, 0.0, 0.6, -0.6, 0.0, 0.7, -1.0, 0.0, /*triangle*/ 0.6, -0.6, 0.0, 0.7, -0.5, 0.0, 0.3, -0.5, 0.0, /*triangle*/ 0.6, -0.6, 0.0, 0.3, -0.5, 0.0, 0.2, -0.6, 0.0, /*triangle*/ 0.3, -0.5, 0.0, 0.2, -0.6, 0.0, 0.3, 0.5, 0.0, /*triangle*/ 0.2, -0.6, 0.0, 0.3, 0.5, 0.0, 0.2, 0.6, 0.0, /*triangle*/ 0.3, 0.5, 0.0, 0.2, 0.6, 0.0, 0.6, 0.6, 0.0, /*triangle*/ 0.3, 0.5, 0.0, 0.6, 0.6, 0.0, 0.7, 0.5, 0.0, /*triangle*/ 0.6, 0.6, 0.0, 0.7, 0.5, 0.0, 0.7, 1.0, 0.0, /*triangle*/ 0.6, 0.6, 0.0, 0.7, 1.0, 0.0, 0.6, 0.9, 0.0, /*triangle*/ 0.7, 1.0, 0.0, 0.6, 0.9, 0.0, -0.6, 0.9, 0.0, /*triangle*/ 0.7, 1.0, 0.0, -0.6, 0.9, 0.0, -0.7, 1.0, 0.0, /*triangle*/ -0.7, 1.0, 0.0, -0.7, 0.5, 0.0, -0.6, 0.9, 0.0, /*triangle*/ -0.7, 0.5, 0.0, -0.6, 0.6, 0.0, -0.6, 0.9, 0.0, /*triangle*/ -0.7, 0.5, 0.0, -0.6, 0.6, 0.0, -0.3, 0.5, 0.0, /*triangle*/ -0.6, 0.6, 0.0, -0.3, 0.5, 0.0, -0.2, 0.6, 0.0, /*triangle*/ -0.3, 0.5, 0.0, -0.2, 0.6, 0.0, -0.3, -0.5, 0.0, /*triangle*/ -0.2, 0.6, 0.0, -0.3, -0.5, 0.0, -0.2, -0.6, 0.0, /*triangle*/ -0.3, -0.5, 0.0, -0.2, -0.6, 0.0, -0.7, -0.5, 0.0, /*triangle*/ -0.2, -0.6, 0.0, -0.7, -0.5, 0.0, -0.6, -0.6, 0,0, /*triangle*/ -0.7, -0.5, 0.0, -0.6, -0.6, 0,0, -0.7, -1.0, 0.0, /*triangle*/ -0.6, -0.6, 0,0, -0.7, -1.0, 0.0, -0.6, -0.9, 0.0, ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); vertexPositionBuffer.itemSize = 3; vertexPositionBuffer.numberOfItems = 72; vertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer); var colors = [ 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); vertexColorBuffer.itemSize = 4; vertexColorBuffer.numItems = 72; } /** * Draw model...render a frame */ function draw() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT); gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer); gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, vertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLES, 0, vertexPositionBuffer.numberOfItems); } /** * Startup function called from html code to start program. */ function startup() { console.log("No bugs so far..."); canvas = document.getElementById("myGLCanvas"); gl = createGLContext(canvas); setupShaders(); setupBuffers(); gl.clearColor(0.0, 0.0, 0.0, 1.0); draw(); }
You have 3 places in your vertex data were you have 0,0 instead of 0.0 var triangleVertices = [ ... /*triangle*/ -0.2, -0.6, 0.0, -0.7, -0.5, 0.0, -0.6, -0.6, 0,0, // <==--- /*triangle*/ -0.7, -0.5, 0.0, -0.6, -0.6, 0,0, // <==--- -0.7, -1.0, 0.0, /*triangle*/ -0.6, -0.6, 0,0, // <==--- -0.7, -1.0, 0.0, -0.6, -0.9, 0.0, ];
Why does a CGAffineTransform applied in steps behave differently than applied at once?
I'm seeing some unexpected, inconsistent behavior when applying transforms in steps as opposed to applying them at once and I'd like to know why. Say we have a label that we'd like to translate to the right 100 and down 50 and then scale up to 1.5 times the original size. So there are two transformations: Translation Scale And say that we are experimenting with two different animations: Perform the translation and scale in parallel Perform the translation, then perform the scale in sequence In the first animation you might do something like this: UIView.animate(withDuration: 5, animations: { label.transform = label.transform.translatedBy(x: 100, y: 50).scaledBy(x: 1.5, y: 1.5) }, completion: nil) And everything behaves how you'd expect. The label translates and scales smoothly at the same time. In the second animation: UIView.animate(withDuration: 5, animations: { label.transform = label.transform.translatedBy(x: 100, y: 50) }, completion: { _ in UIView.animate(withDuration: 5, animations: { label.transform = label.transform.scaledBy(x: 1.5, y: 1.5) }, completion: nil) }) The label translates correctly, and then boom, it jumps unexpectedly and then starts to scale. What causes that sudden, unexpected jump? From inspecting the matrices for each transform (the parallelized and the sequential transforms) the values are the same, as would be expected. Parallelized Animation transform before translate and scale: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0) translate and scale transform: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0) transform after translate and scale: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0) Sequential Animation transform before translation: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0) translation transform: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0) transform after translation: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0) transform before scale: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 50.0) scale transform: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0) transform after scale: CGAffineTransform(a: 1.5, b: 0.0, c: 0.0, d: 1.5, tx: 100.0, ty: 50.0) So what is it that causes the sudden jump?
You need to understand how animation works in iOS. Your animation closure block runs right away and the final values are assigned to the object straight away (This is one of the most important points that a lot of people forget). All the animation block does is that it makes it appear to take that much time. Let me elaborate with an example. let x = UIView() x.alpha = 0 //At this point, alpha is 0 UIView.animate(withDuration: 5, animations: { x.alpha = 1 }, completion: nil) //At this point, alpha is 1 right away. But the animation itself will take 5 seconds With that in mind, let's look at the second example that you posted UIView.animate(withDuration: 5, animations: { label.transform = label.transform.translatedBy(x: 100, y: 50) }, completion: { _ in UIView.animate(withDuration: 5, animations: { label.transform = label.transform.scaledBy(x: 1.5, y: 1.5) }, completion: nil) }) The first animation runs and translates your view right away. It only takes 5 seconds to move there but your view's x & y values have already changed. Upon completion, you scale it resulting in a weird behaviour.
CAGradientLayer not changing the background color
I want to create a gradient as a background color for my UIView. I wrote this code gradient.colors = [UIColor.blue,UIColor.yellow] gradient.locations = [0.0 , 1.0] gradient.startPoint = CGPoint(x: 0.0, y: 1.0) gradient.endPoint = CGPoint(x: 1.0, y: 1.0) gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height) self.view.layer.insertSublayer(gradient, at: 0) but the view still the same set on the Interface Builde. If I add this line before the code self.view.backgroundColor = UIColor.clear the background color changes to white
let gradient: CAGradientLayer = CAGradientLayer() gradient.colors = [UIColor.blue.cgColor, UIColor.yellow.cgColor] gradient.locations = [0.0 , 1.0] gradient.startPoint = CGPoint(x: 0.0, y: 1.0) gradient.endPoint = CGPoint(x: 1.0, y: 1.0) gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height) self.view.layer.insertSublayer(gradient, at: 0) try this code. It works for me swift 3
Creating and assigning CGRect to a UIView within a for loop
I am looping through a [UIView], setting their frames, then adding them as subviews to a UIScrollView. In the code I am assigning a random background colour so I can differentiate the views from each other for testing purposes: for i in 0...questionViews.count - 1 { let hue: CGFloat = CGFloat(arc4random() % 256) / 256 let saturation: CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5 let brightness: CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5 questionViews[i].backgroundColor = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1) questionViews[i].frame = CGRect(x: screen.width * CGFloat(i), y: 0, width: screen.width, height: screen.height) questionsScrollView!.addSubview(questionViews[i]) } However, if I loop through these and print them: for i in 0...questionViews.count - 1 { print(questionViews[i].frame) } the result will be: (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) (3000.0, 0.0, 375.0, 667.0) Why does every CGRect have final value of x from the for-loop? Edit: The questionViews array is set in the init with just empty CGRects to begin with: questionViews = [UIView](count: numberOfQuestions, repeatedValue: UIView(frame: CGRect()))
When creating an array with repeated values of a reference type , it only creates one item and points all indexes to that. So in your for loop you're acutely setting the frame of all indexes of that one UIView over and over again. replace this: questionViews = [UIView](count: numberOfQuestions, repeatedValue: UIView(frame: CGRect())) with var questionViews = [UIView]() for _ in 0..<numberOfQuestions { questionViews.append(UIView(frame: CGRect())) }
How to do Picking via IdMapping in Scenejs?
We have ONE huge Json Mesh like this which we render with scenejs: {"vertices":[ 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 1.0, 0.0, 2.0, 0.0, 2.0, 2.0, //... next object ], "normals":[ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, //... next object ], "colors":[ 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, //... next object ], "idMapColors":[ 0.0, 0.0, 0.0, 0.756, 0.0, 0.0, 0.0, 0.756, 0.0, 0.0, 0.0, 0.756, 0.0, 0.0, 0.0, 0.756, //... next object ]} The idMapColors are unique for each "object" and can be converted into an id to provide additional information. We now want to render the mesh with normal colors on screen and with idMapColors in a second rendering path. We than want to read out the color value in the second FrameBuffer (for idMapColors) at a specific Point(Mouse Position). How to do this in Scenejs? We could render the idMapColors to a Framebuffer, but how to access its data? On the wiki at https://github.com/xeolabs/scenejs/wiki/frameBuf we found that picking is in further work, is there any possibility to do this at the moment?