I hope you can help me with this arduino problem.
I have a rotary encoder hooked up to a servo, and want to achieve that linear relationship of low speed = low angle and high speed = high angle;
It is generally working, this is snapshot from my serial monitor:
spd = 0
input angle = 0
.
spd = 2863304
input angle = 7023
.
spd = 34
input angle = 10
.
spd = 0
input angle = 0
.
My concern here is that sudden jump to a number such as 2863304, it happens frequently, I'm thinking it is a glitch and I wish to remove it, I would very appreciate it if someone can provide some advice!
Related
I was trying to implement the IBVS algorithm (the one explained in the Introduction here) in MATLAB myself, but I am facing the following problem : The algorithm seems to work only for the cases that the camera does not have to change its orientation in respect to the world frame.For example, if I just try to make one vertex of the initial (almost) square go closer to its opposite vertex, the algorithm does not work, as can be seen in the following image
The red x are the desired projections, the blue circles are the initial ones and the green ones are the ones I get from my algorithm.
Also the errors are not exponentially dereasing as they should.
What am I doing wrong? I am attaching my MATLAB code which is fully runable. If anyone could take a look, I would be really grateful. I took out the code that was performing the plotting. I hope it is more readable now. Visual servoing has to be performed with at least 4 target points, because else the problem has no unique solution. If you are willing to help, I would suggest you take a look at the calc_Rotation_matrix() function to check that the rotation matrix is properly calculated, then verify that the line ds = vc; in euler_ode is correct. The camera orientation is expressed in Euler angles according to this convention. Finally, one could check if the interaction matrix L is properly calculated.
function VisualServo()
global A3D B3D C3D D3D A B C D Ad Bd Cd Dd
%coordinates of the 4 points wrt camera frame
A3D = [-0.2633;0.27547;0.8956];
B3D = [0.2863;-0.2749;0.8937];
C3D = [-0.2637;-0.2746;0.8977];
D3D = [0.2866;0.2751;0.8916];
%initial projections (computed here only to show their relation with the desired ones)
A=A3D(1:2)/A3D(3);
B=B3D(1:2)/B3D(3);
C=C3D(1:2)/C3D(3);
D=D3D(1:2)/D3D(3);
%initial camera position and orientation
%orientation is expressed in Euler angles (X-Y-Z around the inertial frame
%of reference)
cam=[0;0;0;0;0;0];
%desired projections
Ad=A+[0.1;0];
Bd=B;
Cd=C+[0.1;0];
Dd=D;
t0 = 0;
tf = 50;
s0 = cam;
%time step
dt=0.01;
t = euler_ode(t0, tf, dt, s0);
end
function ts = euler_ode(t0,tf,dt,s0)
global A3D B3D C3D D3D Ad Bd Cd Dd
s = s0;
ts=[];
for t=t0:dt:tf
ts(end+1)=t;
cam = s;
% rotation matrix R_WCS_CCS
R = calc_Rotation_matrix(cam(4),cam(5),cam(6));
r = cam(1:3);
% 3D coordinates of the 4 points wrt the NEW camera frame
A3D_cam = R'*(A3D-r);
B3D_cam = R'*(B3D-r);
C3D_cam = R'*(C3D-r);
D3D_cam = R'*(D3D-r);
% NEW projections
A=A3D_cam(1:2)/A3D_cam(3);
B=B3D_cam(1:2)/B3D_cam(3);
C=C3D_cam(1:2)/C3D_cam(3);
D=D3D_cam(1:2)/D3D_cam(3);
% computing the L matrices
L1 = L_matrix(A(1),A(2),A3D_cam(3));
L2 = L_matrix(B(1),B(2),B3D_cam(3));
L3 = L_matrix(C(1),C(2),C3D_cam(3));
L4 = L_matrix(D(1),D(2),D3D_cam(3));
L = [L1;L2;L3;L4];
%updating the projection errors
e = [A-Ad;B-Bd;C-Cd;D-Dd];
%compute camera velocity
vc = -0.5*pinv(L)*e;
%change of the camera position and orientation
ds = vc;
%update camera position and orientation
s = s + ds*dt;
end
ts(end+1)=tf+dt;
end
function R = calc_Rotation_matrix(theta_x, theta_y, theta_z)
Rx = [1 0 0; 0 cos(theta_x) -sin(theta_x); 0 sin(theta_x) cos(theta_x)];
Ry = [cos(theta_y) 0 sin(theta_y); 0 1 0; -sin(theta_y) 0 cos(theta_y)];
Rz = [cos(theta_z) -sin(theta_z) 0; sin(theta_z) cos(theta_z) 0; 0 0 1];
R = Rx*Ry*Rz;
end
function L = L_matrix(x,y,z)
L = [-1/z,0,x/z,x*y,-(1+x^2),y;
0,-1/z,y/z,1+y^2,-x*y,-x];
end
Cases that work:
Ad=2*A;
Bd=2*B;
Cd=2*C;
Dd=2*D;
Ad=A+1;
Bd=B+1;
Cd=C+1;
Dd=D+1;
Ad=2*A+1;
Bd=2*B+1;
Cd=2*C+1;
Dd=2*D+1;
Cases that do NOT work:
Rotation by 90 degrees and zoom out (zoom out alone works, but I am doing it here for better visualization)
Ad=2*D;
Bd=2*C;
Cd=2*A;
Dd=2*B;
Your problem comes from the way you move the camera from the resulting visual servoing velocity. Rather than
cam = cam + vc*dt;
you should compute the new camera position using the exponential map
cam = cam*expm(vc*dt)
Scenario:
I m experimenting the thermocouple amplifier (SN-6675) with Arduino DUE.
After i'm included MAX6675 library, Arduino can measured room temperature.
However, Temp measured from arduino have 2 issues,
1) offset compare to "Fluke thermometer"
2) have tons of noise, and keep fluctuated after taking average of each 5 temperature sample.
eg, Fluke thermometer got 28.9C at room temp, arduino got 19.75~45.75C
Question: Any method/filter to reduce the measured noise, and gives a steady output?
Codes is attached for reference.
#include <MAX6675.h>
//TCamp Int
int CS = 7; // CS pin on MAX6675
int SO = 8; // SO pin of MAX6675
int SCKpin = 6; // SCK pin of MAX6675
int units = 1; // Units to readout temp (0 = ˚F, 1 = ˚C)
float error = 0.0; // Temperature compensation error
float tmp = 0.0; // Temperature output variable
//checking
int no = 0;
MAX6675 temp0(CS,SO,SCKpin,units,error); // Initialize the MAX6675 Library for our chip
void setup() {
Serial.begin(9600); // initialize serial communications at 9600 bps:
}
void loop() {
no= no + 1;
tmp = temp0.read_temp(5); // Read the temp 5 times and return the average value to the var
Serial.print(tmp);
Serial.print("\t");
Serial.println(no);
delay(1000);
}
Any method/filter to reduce the measured noise, and gives a steady output?
The Kalman filter is pretty much the standard method for this:
Kalman filtering, also known as linear quadratic estimation (LQE), is an algorithm that uses a series of measurements observed over time, containing noise (random variations) and other inaccuracies, and produces estimates of unknown variables that tend to be more precise than those based on a single measurement alone.
If your background isn't maths, don't be put off by the formulas that you come across. In the single-variable case like yours, the filter is remarkably easy to implement, and I am sure googling will find a few implementations.
The filter will give you an estimate of the temperature as well an estimate of the variance of the temperature (the latter gives you an idea about how confident the filter is about its current estimate).
You may want to go for a simpler averaging algorithm. This is not as elegant as a low pass algorithm but may be adequate for your case. These algorithms are plentiful on the web.
You can monkey around with the number of samples you take to balance the compromise between latency and stability. You may want to start with 10 samples and work from there.
I need to control the sound play speed so I extract sample data from the sound file but how can I control the volume then as SoundTranform.volume has no effect?
private function onSampleData(event:SampleDataEvent):void
{
var l:Number;
var r:Number;
var outputLength:int = 0;
while (outputLength < 2048)
{
_loadedMP3Samples.position = int(_phase) * 8; // 4 bytes per float and two channels so the actual position in the ByteArray is a factor of 8 bigger than the phase
l = _loadedMP3Samples.readFloat(); // read out the left and right channels at this position
r = _loadedMP3Samples.readFloat(); // read out the left and right channels at this position
event.data.writeFloat(l); // write the samples to our output buffer
event.data.writeFloat(r); // write the samples to our output buffer
outputLength++;
_phase += _playbackSpeed;
if (_phase < 0)
_phase += _numSamples;
else if (_phase >= _numSamples)
_phase -= _numSamples;
}
}
Volume:
use say var volume: Number = 1.0 as a field variable. 0.0 for mute, 1.0 for original volume. Alter in other methods. However tweening this variable will be appreciated by listeners.
event.data.writeFloat(volume * l);
event.data.writeFloat(volume * r);
Speed:
You have to resample and use interpolation to define the intermediate values.
It's mathematically involved, but I'm sure there's a ton of libraries that can do this for you. But hey, here's a tutorial that tells you how apparently:
http://www.kelvinluck.com/2008/11/first-steps-with-flash-10-audio-programming/
Edit: Oh, You used this tutorial... You could have said.
modify _playbackSpeed. 1.0 is full speed. 2.0 is double speed.
I recently recorded the EEG signal with sampling rate of 256Hz.The signal will band passed at 4-64Hz.I need a code to filter the eeg data.Is there any type of filter in matlab is most suitable to filter the artifact or noise from the signal??
You can apply a notch filter at 50 or 60 Hz
Artifacts from eye movements generally have a 2-5 Hz frequency range, So you can apply a high pass filter out there.
Wavelets have a thresholding mechanism to filter out noise (hard and soft thresholding) using wavelet packet decomposition.
in case that your Fs =1000 Hz, use this code to be able to filter the signal and extract the features bands (alpha, beta, ...)
S = "your EEG-Data-Row";
waveletFunction = 'db8' OR 'sym8' ;
[C,L] = wavedec(S,8,waveletFunction);
%% Calculation The Coificients Vectors
cD1 = detcoef(C,L,1); %NOISY
cD2 = detcoef(C,L,2); %NOISY
cD3 = detcoef(C,L,3); %NOISY
cD4 = detcoef(C,L,4); %NOISY
cD5 = detcoef(C,L,5); %GAMA
cD6 = detcoef(C,L,6); %BETA
cD7 = detcoef(C,L,7); %ALPHA
cD8 = detcoef(C,L,8); %THETA
cA8 = appcoef(C,L,waveletFunction,8); %DELTA
%%%% Calculation the Details Vectors
D1 = wrcoef('d',C,L,waveletFunction,1); %NOISY
D2 = wrcoef('d',C,L,waveletFunction,2); %NOISY
D3 = wrcoef('d',C,L,waveletFunction,3); %NOISY
D4 = wrcoef('d',C,L,waveletFunction,4); %NOISY
D5 = wrcoef('d',C,L,waveletFunction,5); %GAMMA
D6 = wrcoef('d',C,L,waveletFunction,6); %BETA
D7 = wrcoef('d',C,L,waveletFunction,7); %ALPHA
D8 = wrcoef('d',C,L,waveletFunction,8); %THETA
A8 = wrcoef('a',C,L,waveletFunction,8); %DELTA
Hope this will help .
I am a fairly intelligent person, but when I see a certain kind of math I might as well be a gigantic moron. I could really use some help here.
I have been researching a ton of things as I learn iOS game development and I came across a formula while doing some searches. Here is the formula:
x(t) = x(0) + v(0)*t + .5 (F/m) * t^2
Also stated was solving for x and y:
Fx = (x(t) - x(0) - vx(0)*t) * 2m/t^2
Fy = (y(t) - y(0) - vy(0)*t) * 2m/t^2
Source: Box2D.org forums
Now for my actual question, what does that mean? Keep in mind that in this situation I am an idiot. It would be great if someone could explain the variables in simple terms and how they relate to box2d. How would I apply this formula? Here is an example of my code (firing projectiles):
- (void)spawnProjectile:(CGPoint)from direction:(CGPoint)direction inParent:(CCNode*)parentNode
{
double curTime = CACurrentMediaTime();
double timeTillShotDies = curTime + SHOT_TYPE1_EXIST_TIME;
b2Body *shotBody = projectileBodyTracker[nextShot];
b2Vec2 moveToPosition = b2Vec2(from.x/PTM_RATIO, from.y/PTM_RATIO);
shotBody->SetTransform(moveToPosition, 0.0);
shotBody->SetActive(true);
CCSprite *shot = [projectiles objectAtIndex:nextShot];
shot.position = ccp(from.x/PTM_RATIO, from.y/PTM_RATIO);
shot.visible = YES;
[projectilesTracker replaceObjectAtIndex:nextShot withObject:[NSNumber numberWithDouble:timeTillShotDies]];
CCParticleSystemQuad *particle = [projectileParticleTracker objectAtIndex:nextShot];
[particle resetSystem];
nextShot++;
if(nextShot >= projectiles.count) nextShot = 0;
// dx2 and dy2 are analog stick values (see below code)
b2Vec2 force = b2Vec2(dx2, dy2);
shotBody->SetLinearVelocity(force);
[AudioController playLaserShot];
}
In this particular chunk of code I am firing from the player at the angle the analog is at. I also would need to use the formula to fire from the enemy to the player. This is a top down space shooter.
So to summarize, how do I solve constant force over time for x and y, in terms of box2d code?
Extra info:
dx2 = (float)joypadBG2.position.x - (float)convertedPoint.x;
dy2 = (float)joypadBG2.position.y - (float)convertedPoint.y;
All objects are preloaded and kept that way. Bodies are set inactive and sprites set invisible. Particle systems are stopped. The opposite is true for using a projectile again.
Thank you very much for any help you may be able to provide. I hope I haven't forgotten anything.
The first equation describes the movement of an object that is subject to a constant force.
The object starts at position x(0) and has speed v(0). Both x and v are vectors, so in a 2d shooter, x(0) would be (x0,y0), or the xy-position, and v(0) would be (vx0, vy0).
If there is no gravity then F=0 on unpropelled projectiles (projectiles without thrusters),
so the velocity will be constant.
x(t1) = x(t0) + vx * (t1-t0)
y(t1) = y(t0) + vy * (t1-t0)
t1-t0 or dt (delta-t) is the time elapsed since the last time you updated the position of the projectile.
If thusters or gravity are excerting force on an object then the velocity will change over time.
vx(t1) = vx(t0) + ax * (t1-t0)
vy(t1) = vy(t0) + ay * (t1-t0)
a is the acceleration. In a game you usually don't care about mass and force, just acceleration. In physics, a = F/m.
Edit 1:
In computer games, you update the position of an object very frequently (typically around 60 times per second). You have the position and velocity of the object at the previous update and you want to calculate the new position.
You update the position by assuming that the velocity was constant:
positionVectorAt(newTime) = positionVector(lastTime) + velocityVector*(newTime - lastTime);
If the velocity of the object is changed you also update the velocity:
velocityVectorAt(newTime) = velocityVector(lastTime) + accelerationVector*(newTime - lastTime);
Let's say we have a sprite at
positionVector.x=100;
positionVector.y=10;
The initial speed is
velocityVector.x = 3;
velocityVector.y = -10;
The sprite is using thrusters which is giving a horizonal acceleration per second of
thrusterVector.x= 5;
and it is also subject to gravity which gives a vertical acceleration per second of
gravityVector.y = -10;
The code to update the sprites position will be:
deltaTime = now - lastTime; // Time elapsed since last position update
// Update the position
positionVector.x = positionVector.x + velocityVector.x * deltaTime;
positionVector.y = positionVector.y + velocityVector.y * deltaTime;
// Update the velocity
velocityVector.x = velocityVector.x + (thrusterVector.x + gravityVector.x) * deltaTime;
velocityVector.y = velocityVector.y + (thrusterVector.y + gravityVector.y) * deltaTime;
// Done! The sprite now has a new position and a new velocity!
Here is a quick explanation:
x(t) = x(0) + v(0)*t + .5 (F/m) * t^2
Fx = (x(t) - x(0) - vx(0)*t) * 2m/t^2
Fy = (y(t) - y(0) - vy(0)*t) * 2m/t^2
These 3 equations are standard movement ones:
t: time
x(t): position at time t
v(t): speed at time t
vx(t): horizontal component of speed at time t
vy(t): vertical component of speed at time t
m: mass
F: force
Fx: horizontal component of the force
Fy: vertical component of the force
So of course, each time you see x(0) or vy(0), these values are taken at time t, i.e. they are initial values. These equations are basic cinematic equations with the basic cinematic variables (position, speed, force, mass).