My if and else if are running at the same time [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've got a program measuring distance from a rocket to the moon, so when the distance is >250, only the if runs. However when the else runs and the distance <=250, the if continues to run while the else runs. If anyone can help me fix it I would be very thankful.
do
{
if (distance >250)
{
time += 1;
y_pos = initial_y_pos - (vel_y * time)/2;
x_pos = initial_x_pos + (vel_x * time)/2;
//Sets the new x and y position when time is flowing so the rocket can move
GFX_DrawLineTo(x_pos, y_pos, 3);
GFX_UpdateDisplay();
distance = sqrt(pow((y_pos-(y+312)),2)+(pow((x_pos-(x+440)),2)));
mars_dist = sqrt(pow((y_pos-150),2)+pow((x_pos-1150),2));
//distance calculation from the rocket to the moon. Needed for sphere of influence
printf("%f\n",distance);
}
else if (distance <=250)
{
y_pos = initial_y_pos - ((vel_y * time) - ((gravity * time)/2));
x_pos = initial_x_pos + ((vel_x * time) - ((gravity * time)/2));
GFX_DrawLineTo(x_pos, y_pos, 3);
GFX_UpdateDisplay();
distance = sqrt(pow((y_pos-(y+312)),2)+(pow((x_pos-(x+440)),2)));
mars_dist = sqrt(pow((y_pos-150),2)+pow((x_pos-1150),2));
//printf("%f\n",distance);
printf("%f\n", x_pos);
}
if (distance <= 50)
//If the rocket either hits moon or mars, this is responsible for recognising that
{
printf("Unlucky! Your rocket crashed into the moon!");
return 0;
}
}
//while (distance > 250);
while ((0 <= x_pos && x_pos <= 1280) || (0 <= y_pos && y_pos <= 1024));

when the else runs and the distance <=250, the if continues to run while the else runs
ok, you mean distance <=250 then the next while turn distance>250
This happens when the computed speed/covered distance is too high and the rocket crosses Mars to be on the other side far than 250 (or the rocket enter inside Mars ?) after the delay time, that means you have to change
y_pos = initial_y_pos - ((vel_y * time) - ((gravity * time)/2));
x_pos = initial_x_pos + ((vel_x * time) - ((gravity * time)/2));
...
distance = sqrt(pow((y_pos-(y+312)),2)+(pow((x_pos-(x+440)),2)));
mars_dist = sqrt(pow((y_pos-150),2)+pow((x_pos-1150),2));
to decrease the speed/covered distance in that case if it is too high. Or may be the speed/covered distance is correct but the rocket reaches the surface or Mars in less than time, so the new position is incorrect and impossible because that supposes the rocket can cross the surface of Mars, you have to detect that case.

Related

c for loop instead of an if statement

distance = (u * t + (0.5 * (a * t * t)));
printf("distance is ");
printf("%0.5f\n", distance);
printf("\n");
if (distance >= height)
{
bounce = ((COR*COR)*height);
printf("The bounce is ");
printf("%0.5f\n", bounce);
bounce_height = bounce;
bounce = ((COR*COR)*bounce_height);
printf("The bounce is ");
printf("%0.5f", bounce);
break;
}
so basically I am making a program to get data values for a bouncing ball and I need to know the bounce heights which is calculated using COR (coefficient of restitution squared) * drop height. I need it to be able to loop through the program so after the first bounce height is calculated that value is then used in the equation to get the next one and so on. I am unsure on how to do this I started with an IF statement but that will only do as many calculations as i program in. Any help with this would be amazing thanks in advance. PS the values for COR and height are asked for from the user early in the program.
You should use a while loop and set a minimum heigth that stops the loop.
Something like:
#define MINIMUM_HEIGTH 0.1
float current_heigth = 2.0;
while (current_heigth > MINIMUM_HEIGTH)
{
printf("Current heigth is %f\n", current_heigth);
current_heigth = calculate_new_heigth_after_bounce...;
}
This will keep printing the heigth after each bounce until the heigth get below MINIMUM_HEIGTH

Im trying to code a Discomfort Index program in C but im stuck [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I've built the main part of the program but the task requires us to add a feature in which if the index is above the "No discomfort" zone, the program returns the decrease in temperature required for the index to be at "No discomfort" (considering humidity is consistent).
The problem im facing is I set a variable named x which i want to represent the decrease in temperature needed but when i try to form a equation to solve for x it only prints 0.Im pretty sure i cant give an equation to the compiler to solve but is there any way i can get the decrease needed printed?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float main()
{
float T, RH, x, y;
printf("Insert current temperature in Celsius: \n");
scanf("%f", &T);
printf("Insert current humidity percentage: \n");
scanf("%f", &RH);
float DI = T - 0.55 * (1 - 0.01 * RH) * (T - 14.5);
if (DI < 21)
printf("No discomfort");
else if (DI >= 21 && DI < 24)
printf("Under 50 percent population feels discomfort");
else if (DI >= 24 && DI < 27)
printf("Most 50 percent population feels discomfort");
else if (DI >= 27 && DI < 29)
printf("Most of population suffers discomfort");
else if (DI >= 29 && DI < 32)
printf("Everyone feels severe stress");
else if (DI >= 32)
printf("State of medical emergency");
if (DI >= 21)
DI=21;
x=(DI - 14.5 * 0.55(1 - 0.01 * RH))/(1 - 0.55(1 - 0.01*RH));
printf("\nThe temperature should be decreased to %.2f degrees\n", x);
return 0;
Any help is appreciated
Your compiler is already telling you what's wrong here:
x=(DI - 14.5 * 0.55(1 - 0.01 * RH))/(1 - 0.55(1 - 0.01*RH));
Something like this:
error: called object type 'double' is not a function or function pointer
That's because 0.55(1) is math, not C. You need a *.
Always enable and inspect your compiler warnings before wondering why your code doesn't work.

MATLAB loop-index issue [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 6 years ago.
Improve this question
Context: I must create a program that describes the motion of a car being tested for a quarter-mile time as part of a performance analysis. This involves time, distance, velocity, acceleration, forces, torque, and rotational speed.
In the last for loop I get the following error with whatever line of code is at the top (in this example the engine torque):
"Attempted to access RPM(2); index out of bounds because numel(RPM)=1."
clear all
close all
clc
time(1) = 0; %[seconds]
dist(1) = 0;
vel(1) = 0;
accel(1) = 0;
RPMmin = 1200;
RPM(1) = RPMmin;
r = 19; %[inches]
wt = 3760; %[pounds]
Ng = [3.253, 2.233, 1.611, 1.243, 1, 0.629]; %{Gear Ratio}
Nd = [3.73]; %differential ratio
dt = 0.1; %time increment
for k = 1:1:6
xntt(k) = Ng(k) * Nd;
xmf(k) = 1 + (0.04 * xntt(k)) + (0.0025 * xntt(k)^2);
gst = 0.25; %gear shift time
end
for i = 1:1:1000
Te(i) = 18.154 + (.1571 * RPM(i)) - (0.0000147 * (RPM(i))^2);
fx(i) = Te(i) * xntt(k)/(r/12);
dV(i + 1) = (32.2/(wt * xmf(k)))*fx(i);
accel(i + 1) = dV(i)/dt;
vel(i + 1) = vel(i) + (dV(i) * dt);
dist(i + 1) = dist(i) + vel(i + 1)*dt;
time(i + 1) = time(i) + dt;
RPM(i) = (vel(i + 1)*60*xntt(k))/((2*pi*r)/12);
end
This happens when i=2 inside the for-loop (second iteration). Depending on RPM, you basically have two choices:
let Te(i) depend on RPM(i-1), so Te(2) will depend on RPM(1) and so on. This will, however, throw an error when i=1 due to the fact that if i=1, then i-1=0 and Matlab allows only positive indices so you need to place an if check inside the loop.
let RPM grow just like Te, so if at iteration i you're writing on Te(i+1), write as well on RPM(i+1).
Both of these approaches lead to a code with no errors (i.e. syntactically correct) but then you must choose the correct approach depending on what your problem is and how such vectors are sort of "linked" together (i.e. your code must be semantically correct as well).

Configuring and limiting output of PI controller

I have implemented simple PI controller, code is as follows:
PI_controller() {
// handling input value and errors
previous_error = current_error;
current_error = 0 - input_value;
// PI regulation
P = current_error //P is proportional value
I += previous_error; //I is integral value
output = Kp*P + Ki*I; //Kp and Ki are coeficients
}
Input value is always between -π and +π.
Output value must be between -4000 and +4000.
My question is - how to configure and (most importantly) limit the PI controller properly.
Too much to comment but not a definitive answer. What is "a simple PI controller"? And "how long is a piece of string"? I don't see why you (effectively) code
P = (current_error = 0 - input_value);
which simply negates the error of -π to π. You then aggregate the error with
I += previous_error;
but haven't stated the cumulative error bounds, and then calculate
output = Kp*P + Ki*I;
which must be -4000 <= output <= 4000. So you are looking for values of Kp and Ki that keep you within bounds, or perhaps don't keep you within bounds except in average conditions.
I suggest an empirical solution. Try a series of runs, filing the results, stepping the values of Kp and Ki by 5 steps each, first from extreme neg to pos values. Limit the output as you stated, counting the number of results that break the limit.
Next, halve the range of one of Kp and Ki and make a further informed choice as to which one to limit. And so on. "Divide and conquer".
As to your requirement "how to limit the PI controller properly", are you sure that 4000 is the limit and not 4096 or even 4095?
if (output < -4000) output = -4000;
if (output > 4000) output = 4000;
To configure your Kp and Ki you really should analyze the frequency response of your system and design your PI to give the desired response. To simply limit the output decide if you need to freeze the integrator, or just limit the immediate output. I'd recommend freezing the integrator.
I_tmp = previous_error + I;
output_tmp = Kp*P + Ki*I_tmp;
if( output_tmp < -4000 )
{
output = -4000;
}
else if( output_tmp > 4000 )
{
output = 4000;
}
else
{
I = I_tmp;
output = output_tmp;
}
That's not a super elegant, vetted algorithm, but it gives you an idea.
If I understand your question correctly you are asking about anti windup for your integrator.
There are more clever ways to to it, but a simple
if ( abs (I) < x)
{
I += previous_error;
}
will prevent windup of the integrator.
Then you need to figure out x, Kp and Ki so that abs(x*Ki) + abs(3.14*Kp) < 4000
[edit] Off cause as macduff states, you first need to analyse your system and choose the korrect Ki and Kp, x is the only really free variable in the above equation.

Noise cancellation setup - combining the microphone's signals intelligently [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I built a noise cancellation setup with two microphones and two different microphone preamplifiers that go to two different channels of a stereo recording.
Here is a sample
http://filestore.to/?d=U5FN2IH96K
I tried
char ergebnis[80];
sprintf(ergebnis, "%s.neu.raw", Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");
if (f == NULL)
{
return;
}
int i = -1;
int r1 = 0;
int r2 = 0;
int l1 = 0;
int l2 = 0;
int l = 0;
int r = 0;
int wo = 0;
int dif = 0;
while (wo != EOF)
{
wo = getc(f);
i++;
if (i == 0)
{
r1 = (unsigned)wo;
}
if (i == 1)
{
r2 = (unsigned)wo;
r = (r2 << 8) + r1; //r1 | r2 << 8;
}
if (i == 2)
{
l1 = (unsigned)wo;
}
if (i == 3)
{
l2 = (unsigned)wo;
l = (l2 << 8) + l1; //l1 | l2 << 8;
dif = r - (l * 2);
putc((char)( (unsigned)dif & 0xff), ausgabe);
putc((char)(((unsigned)dif >> 8) & 0xff), ausgabe);
i = -1;
}
}
when the magic happens in
dif = r - (l * 2);
But this does not eliminate the noise surrounding it, all it does is create crackling sounds.
How could I approach this task with my setup instead? I prefer practical solutions over "read this paper only the author of the paper understands".
While we are at it, how do I normalize the final mono output to make it as loud as possible without clipping?
I don't know why you would expect this
dif = r - (l * 2);
to cancel noise, but I can tell you why it "create[s] crackling sounds". The value in dif is often going to be out of range of 16-bit audio. When this happens, your simple conversion function:
putc((char)( (unsigned)dif & 0xff), ausgabe);
putc((char)(((unsigned)dif >> 8) & 0xff), ausgabe);
will fail. Instead of a smooth curve, your audio will jump from large positive to large negative values. If that confuses you, maybe this post will help.
Even if you solve that problem, a few things aren't clear, not the least of which is that for active noise canceling to work you usually assume that one mike provides a source of noise and the other provides signal + noise. Which is which in this case? Did you just place two mikes next to each other and hope to hear some sound source with less ambient noise after some simple arithmetic? That won't work, since they are both hearing different combinations of signal and noise (not just in amplitude, but time as well). So you need to answer 1. which mike is the source of signal and which is the source of noise? 2. what kind of noise are you trying to cancel? 3. what distinguishes the mikes in their ability to hear signal and noise? 4. etc.
Update: I'm still not clear on your setup, but here's something that might help:
You might have a setup where your signal is strong in one mike and weak in the other, and a noise is applied to both mikes. In all likelyhood, there will be signal leak into both mikes. Nevertheless, we will assume
l = noise1
r = signal + noise2
Note that I have not assumed the same noise values for l and r, this reflects the reality that the two mikes will be picking up different noise values due to time delays and other factors. However, it is often the case (and may or may not be the case in your setup) that noise1 and noise2 are correlated at low frequencies. Thus, if we have a low pass filter, lp, we can achieve some noise reduction in the low frequencies as follows:
out = r - lp(l) = signal + noise2 - lp(noise1)
This, of course, assumes that the noise level at l and r is the same, which it may or may not be, depending on your setup. You may want to leave a manual parameter for this purpose for manual tuning at the end:
out = r - g*lp(l)
where g is your tuning parameter and close to 1. I believe in some high-end noise reduction systems, g is constantly tuned automatically.
Selecting a cutoff frequency for your lp filter is all that remains. An approximation you could use is that the highest frequency you can cancel has a wavelength equal to 1/4 the distance between the mikes. Of course, I'm REALLY waving my arms with that, because it depends a lot on where the sound is coming from, how directional your mikes are and so on, but it's a starting point.
Sample calculation for mikes that are 3 inches apart:
Speed of sound = 13 397 inches / sec
desired wavelength = 4*3 inches = 12 inches
frequency = 13,397 / 12 = 1116 Hz
So your filter should have a cutoff frequency of 1116 Hz if the mikes are 3 inches apart.
Expect this setup to cancel a significant amount of your signal below the cutoff frequency as well, if there is bleed.

Resources