Get drone flying state vi Drone kit - dronekit-python

Is there a way to get the flying state of the drone using dronekit ?
and by flying state I mean: Landed, Taking off, hovering, flying, landing

Yes, you can get the flying state of the drone for some of the cases you list. Of course this will all depend on how you've programmed your flight behavior with dronekit. Here is what I would do:
Hovering: self.vehicle.mode.name == "LOITER"
Flying: self.vehicle.mode.name in ("GUIDED","AUTO")
Landing: self.vehicle.mode.name == "LAND"
Landed: self.vehicle.armed == False (the quadcopter props should automatically disarm once the drone has completed the landing procedure)
Taking off: no straightforward answer here but you could infer it from the altitude of your drone. If you've sent a takeoff(target_alt) instruction and the drone has not reached the target_alt then you're probably still taking off.

Related

NAO robot grasps a ball on the ground

I create a timeline on Choregraph,and turn to the animation mode.I have trouble in making NAO crouch and making its hand able to reach the ball on the ground.How to record every gesture,such as intervals between two gestures,how many gesture I should record.Meanwhile,the robot often falls down...How can I adjust the gesture.
Choregraphe's animation mode helped you design grossly the movement of the robot, but it is up to you refine the result by spacing the key frames properly, and tuning the movement to maintain the balance.
Robot animation requires time and skill, and includes specific challenges :
you may have to move the robot to positions that are not balanced, which the robot requires too much strength to maintain, resulting in hot joints*, loss of strength, or the robot falling. Hence you need to be able to carry the robot regularly to record or test the robot's position.
the positions are irremediably mechanically constrained.
real joints are imperfect, have limited maximum strength and speed, and have play.
real world have real obstacles, and the robot tries to avoid them, altering the desired trajectories.
*When you get hot joints, just let the robot sit for 2 minutes, you do not need to reboot it.

counting pulses from a Mechanical water meter with Two inputs

I want to count the number of pulses from a mechanical water meter using an STM32L Microcontroller. The outputs of the water meter are from TWO REED switches.
The operation of the Switches is explained as follows:
the two Reed switches would be operated "ON" OR "OFF" respectively by the magnet fitted to the pointer or gear during its running on the register, but never "ON" at the same time.
The two Reed switches operate two "ON" and two "OFF" in one round of the pointer/the gear means one signal output.
How can I read in the two inputs and be able to count the number of pulses in C? Note: 1 pulse = 100 liters.
I'm not sure what you're actually asking because what you seem to be asking is so simple whether you poll or use edge triggered interrupts. The main issue is debouncing the switch signals. For debouncing you should determine the maximum flow rate of your meter, which you don't really care about directly, but it will let you calculate the maximum switch period. Use some significant portion of the minimum on or off time to perform your debounce.
The point of having two switches 180 degree apart, such that only one switch can be made at a time, is that no switch debouncing is needed.
In practice the code would need to be more sophisticated, but the basic algorithm can be represented by this:
while(1) {
while(switchA() == 0); // wait for switch A to be made
litres += 100; // clock up unit volume
display(litres); // tell the user
while(switchB() == 0); // wait for switch B to be made
}
It does not matter how many pulses come from a reed switch, when it is near the magnet - all but the first pulse will be ignored, because the algorithm is then looking at the other switch.

Push a button while reading sensor in Arduino

I've been doing a little thermometer project to learn Arduino and there is an annoying thing that I have no idea how to resolve.
I have two push buttons to set Min and Max temperature and when I push the buttons it's supposed to set the Min and Max temperature on display.
The problem is that sometimes (50% of times) when I push the buttons during the reading of the temperature sensor, the buttons don't work. I press it but the Min/Max temperature are not set because Arduino is stuck in reading the temperature sensor.
Is there any trick to solve this kind of problem? If I had a keyboard for typing some number for example I imagine I would have the same problem and It's not "user-friendly".
Here is an example of part of the code I'm using:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
//variables declaration...
void setup() {
sensors.begin();
sensors.getAddress(sensor1, 0);
pinMode(buzzer, OUTPUT);
pinMode(btBuzzer, INPUT);
pinMode(btMin, INPUT);
pinMode(btMax, INPUT);
}
void loop() {
readButtons();
playBuzzer();
readTemperature();
printDisplay();
delay(150);
}
void readButtons(){
if(digitalRead(btBuzzer)){
buzzerOn = !buzzerOn;
}
if(digitalRead(btMin)){
if(tempMin == 69)
tempMin = 59;
else
tempMin++;
}
if(digitalRead(btMax)){
if(tempMax == 75)
tempMax = 63;
else
tempMax++;
}
}
void readTemperature(){
sensors.requestTemperatures();
temperature = sensors.getTempC(sensor1);
}
//lots of other methods
As others have pointed out here, the button press may not happen at the same time as you query the pin with digitalRead(btBuzzer). This type of problem is what so called "interrupts" were invented for, which allow you to respond to events that may occur while you are not monitoring the pin of interest.
For example, the Arduino UNO R3 allow for interrupts on pin 2 and 3. You should look up the reference for attachInterrupt(). The processor will execute a callback function in the event (the "interrupt") that you register for (e.g. the voltage on pin 2 changing from low to high). This means that you will no longer have to call a readButtons() function from your main loop.
Some of the best ways to learn coding exist in how to answer this question.
What I'd like to suggest doing is to try timing your code. Remember that loop() is creating a repeating structure. So we can say things like how long does the computer take to run each loop. When we have an interrupt like a button press how does that effect the iteration through the loop and is it conditional about how to rest the processor (the delay).
The delay is required so as to not do what's called "spin" the processor (have the processor as quickly as it can do a lot of work to accomplish absolutely nothing). However, notice how the code doesn't account for work done changing how long we delay?
Now let's imagine the processor actually can go through that loop more than one time very quickly. Remember delay of only 150 milliseconds isn't a lot of time. So maybe one button press will be enough to set tempMin from 59 to 69 in rapid succession and loop several times over rather than just increasing one number at a time.
What you have here is a chance to learn debugging. First trick is to determine is the loop running too fast or too slow; are you getting desired functionality or not and finally if you can reask the question after you know if it's happening too fast or slow.
For now, I'd recommend taking a look at global variables and finite state machines (i.e. if you're in a state of button press, don't accept any further button presses until you're done with your state and only transition in known ways).

How do I reliably pause the state of a game?

So I have a couple instances where I want to be able to 'freeze' the state of my game. It's a top-down scroller, and I want to give the player the ability to pause the scrolling of the screen for a short time by using a powerup (if you fall to the bottom of the screen you die). I also want to pause the game as it is starting, and draw a 3, 2, 1, go! to give the player time to get ready, because right now as soon as you hit play, the screen starts scrolling.
I have been using Timer to accomplish this, however it doesn't work if I want to freeze the screen on consecutive occasions. Like if a player uses a freeze, the screen sucesssfully freezes, but if they quickly use another freeze, it doesn't work. There seems to be an unintended cool-down. I have a similar problem for the 'intro delay' I explained earlier. For some reason it only works on the first 2 levels. Here is how I am using Timer.
if(gameState != STATE.frozen) {
camera.translate(0, (float) scrollSpeed);
staminaBar.setPosition(staminaBar.getX(), (float) (staminaBar.getY()+scrollSpeed));
staminaMeter.setPosition(staminaMeter.getX(), (float) (staminaMeter.getY()+scrollSpeed));
healthBar.setPosition(healthBar.getX(), (float) (healthBar.getY()+scrollSpeed));
healthMeter.setPosition(healthBar.getX(), (float) (healthMeter.getY()+scrollSpeed));
boostBar.setPosition(boostBar.getX(), (float) (boostBar.getY()+scrollSpeed));
boostMeter.setPosition(boostMeter.getX(), (float) (boostMeter.getY()+scrollSpeed));
screenCeiling += (float) scrollSpeed;
screenFloor += (float) scrollSpeed;
}
else {
Timer.schedule(new Task() { //freeze the screen for 5 seconds
#Override
public void run() {
gameState = STATE.playing;
}
}, 5);
}
From what I understand, it waits 5 second before resuming the game to the 'playing' state. But like I said, this only works when activated between large intervals and I don't know why. Is there a better way I can be doing this?
As for the intro delay, this may be a question better asked seperate, but I use the same method, but it doesn't let me draw sprites over my tiledmap, so if anyone knows how to do that please include it in your response
Assuming the code you posted is in your render loop, then whenever you are not in the frozen state, you are creating a new timer task on every frame. So if you freeze for 5 seconds and your game is running at 60fps, you will create 300 timer tasks, each of which is going to force the game to go back to playing state. The last one won't fire until 5 seconds after the first one fires, so there will be a five second "cooldown" during which you cannot change the state to anything besides playing, because there will be another timer task firing on every frame during that time.
You need to ensure that you only create one timer task, only when you first enter frozen state.
I do have a suggestion...instead of using a state to freeze the game, use a variable that's multiplied by scrollSpeed. Change that variable from one to zero when the player uses the powerup. Then you can do fancy stuff like quickly interpolating from one to zero so the speed change isn't so abrupt. And it will probably make your code simpler since there would be one less state that must be handled differently in the algorithm.
Check your gameState variable in the render method and if the game is playing, then update the game as usual and draw it.
If the game is not playing then skip the game's update method and create a time delay from the current time:
endTime = TimeUtils.millis()+5000;
Then each time through the render method check to see if current time is greater than the end time. When the current time is past your delay time, set gameState back to playing and have the game go back to updating.
You'll have to have another boolean flag so you only set the endTime once (you don't want to keep resetting this each time through the render loop), or if "STATE" is an enum, then include an option for "justPaused" for the exact frame that you pause the game, set the end time, then set STATE to "notPlaying".
You can also use this to create an alternative "update" method where you can update your countdown sprites, but not update the game itself. When the game is playing this other update method will be skipped.

Given an audio stream, find when a door slams (sound pressure level calculation?)

Not unlike a clap detector ("Clap on! clap clap Clap off! clap clap Clap on, clap off, the Clapper! clap clap ") I need to detect when a door closes. This is in a vehicle, which is easier than a room or household door:
Listen: http://ubasics.com/so/van_driver_door_closing.wav
Look:
It's sampling at 16bits 4khz, and I'd like to avoid lots of processing or storage of samples.
When you look at it in audacity or another waveform tool it's quite distinctive, and almost always clips due to the increase in sound pressure in the vehicle - even when the windows and other doors are open:
Listen: http://ubasics.com/so/van_driverdoorclosing_slidingdoorsopen_windowsopen_engineon.wav
Look:
I expect there's a relatively simple algorithm that would take readings at 4kHz, 8 bits, and keep track of the 'steady state'. When the algorithm detects a significant increase in the sound level it would mark the spot.
What are your thoughts?
How would you detect this event?
Are there code examples of sound pressure level calculations that might help?
Can I get away with less frequent sampling (1kHz or even slower?)
Update: Playing with Octave (open source numerical analysis - similar to Matlab) and seeing if the root mean square will give me what I need (which results in something very similar to the SPL)
Update2: Computing the RMS finds the door close easily in the simple case:
Now I just need to look at the difficult cases (radio on, heat/air on high, etc). The CFAR looks really interesting - I know I'm going to have to use an adaptive algorithm, and CFAR certainly fits the bill.
-Adam
Looking at the screenshots of the source audio files, one simple way to detect a change in sound level would be to do a numerical integration of the samples to find out the "energy" of the wave at a specific time.
A rough algorithm would be:
Divide the samples up into sections
Calculate the energy of each section
Take the ratio of the energies between the previous window and the current window
If the ratio exceeds some threshold, determine that there was a sudden loud noise.
Pseudocode
samples = load_audio_samples() // Array containing audio samples
WINDOW_SIZE = 1000 // Sample window of 1000 samples (example)
for (i = 0; i < samples.length; i += WINDOW_SIZE):
// Perform a numerical integration of the current window using simple
// addition of current sample to a sum.
for (j = 0; j < WINDOW_SIZE; j++):
energy += samples[i+j]
// Take ratio of energies of last window and current window, and see
// if there is a big difference in the energies. If so, there is a
// sudden loud noise.
if (energy / last_energy > THRESHOLD):
sudden_sound_detected()
last_energy = energy
energy = 0;
I should add a disclaimer that I haven't tried this.
This way should be possible to be performed without having the samples all recorded first. As long as there is buffer of some length (WINDOW_SIZE in the example), a numerical integration can be performed to calculate the energy of the section of sound. This does mean however, that there will be a delay in the processing, dependent on the length of the WINDOW_SIZE. Determining a good length for a section of sound is another concern.
How to Split into Sections
In the first audio file, it appears that the duration of the sound of the door closing is 0.25 seconds, so the window used for numerical integration should probably be at most half of that, or even more like a tenth, so the difference between the silence and sudden sound can be noticed, even if the window is overlapping between the silent section and the noise section.
For example, if the integration window was 0.5 seconds, and the first window was covering the 0.25 seconds of silence and 0.25 seconds of door closing, and the second window was covering 0.25 seconds of door closing and 0.25 seconds of silence, it may appear that the two sections of sound has the same level of noise, therefore, not triggering the sound detection. I imagine having a short window would alleviate this problem somewhat.
However, having a window that is too short will mean that the rise in the sound may not fully fit into one window, and it may apppear that there is little difference in energy between the adjacent sections, which can cause the sound to be missed.
I believe the WINDOW_SIZE and THRESHOLD are both going to have to be determined empirically for the sound which is going to be detected.
For the sake of determining how many samples that this algorithm will need to keep in memory, let's say, the WINDOW_SIZE is 1/10 of the sound of the door closing, which is about 0.025 second. At a sampling rate of 4 kHz, that is 100 samples. That seems to be not too much of a memory requirement. Using 16-bit samples that's 200 bytes.
Advantages / Disadvantages
The advantage of this method is that processing can be performed with simple integer arithmetic if the source audio is fed in as integers. The catch is, as mentioned already, that real-time processing will have a delay, depending on the size of the section that is integrated.
There are a couple of problems that I can think of to this approach:
If the background noise is too loud, the difference in energy between the background noise and the door closing will not be easily distinguished, and it may not be able to detect the door closing.
Any abrupt noise, such as a clap, could be regarded as the door is closing.
Perhaps, combining the suggestions in the other answers, such as trying to analyze the frequency signature of the door closing using Fourier analysis, which would require more processing but would make it less prone to error.
It's probably going to take some experimentation before finding a way to solve this problem.
You should tap in to the door close switches in the car.
Trying to do this with sound analysis is overengineering.
There are a lot of suggestions about different signal processing
approaches to take, but really, by the time you learn about detection
theory, build an embedded signal processing board, learn the processing
architecture for the chip you chose, attempt an algorithm, debug it, and then
tune it for the car you want to use it on (and then re-tune and re-debug
it for every other car), you will be wishing you just stickey taped a reed
switch inside the car and hotglued a magnet to the door.
Not that it's not an interesting problem to solve for the dsp experts,
but from the way you're asking this question, it's clear that sound
processing isn't the route you want to take. It will just be such a nightmare
to make it work right.
Also, the clapper is just an high pass filter fed into a threshold detector. (plus a timer to make sure 2 claps quickly enough together)
There is a lot of relevant literature on this problem in the radar world (it's called detection theory).
You might have a look at "cell averaging CFAR" (constant false alarm rate) detection. Wikipedia has a little bit here. Your idea is very similar to this, and it should work! :)
Good luck!
I would start by looking at the spectral. I did this on the two audio files you gave, and there does seem to be some similarity you could use. For example the main difference between the two seems to be around 40-50Hz. My .02.
UPDATE
I had another idea after posting this. If you can, add an accelerometer onto the device. Then correlate the vibrational and acoustic signals. This should help with cross vehicle door detection. I'm thinking it should be well correlated since the sound is vibrationally driven, wheres the stereo for example, is not. I've had a device that was able to detect my engine rpm with a windshield mount (suction cup), so the sensitivity might be there. (I make no promises this works!)
(source: charlesrcook.com)
%% Test Script (Matlab)
clear
hold all %keep plots open
dt=.001
%% Van driver door
data = wavread('van_driver_door_closing.wav');
%Frequency analysis
NFFT = 2^nextpow2(length(data));
Y = fft(data(:,2), NFFT)/length(data);
freq = (1/dt)/2*linspace(0,1,NFFT/2);
spectral = [freq' 2*abs(Y(1:NFFT/2))];
plot(spectral(:,1),spectral(:,2))
%% Repeat for van sliding door
data = wavread('van_driverdoorclosing.wav');
%Frequency analysis
NFFT = 2^nextpow2(length(data));
Y = fft(data(:,2), NFFT)/length(data);
freq = (1/dt)/2*linspace(0,1,NFFT/2);
spectral = [freq' 2*abs(Y(1:NFFT/2))];
plot(spectral(:,1),spectral(:,2))
The process for finding distinct spike in audio signals is called transient detection. Applications like Sony's Acid and Ableton Live use transient detection to find the beats in music for doing beat matching.
The distinct spike you see in the waveform above is called a transient, and there are several good algorithms for detecting it. The paper Transient detection and classification in energy matters describes 3 methods for doing this.
I would imagine that the frequency and amplitude would also vary significantly from vehicle to vehicle. Best way to determine that would be taking a sample in a Civic versus a big SUV. Perhaps you could have the user close the door in a "learning" mode to get the amplitude and frequency signature. Then you could use that to compare when in usage mode.
You could also consider using Fourier analysis to eliminate background noises that aren't associated with the door close.
Maybe you should try to detect significant instant rise in air pressure that should mark a door close. You can pair it with this waveform and sound level analysis and these all might give you a better result.
On the issue of less frequent sampling, the highest sound frequency which can be captured is half of the sampling rate. Thus, if the car door sound was strongest at 1000Hz (for example) then a sampling rate below 2000Hz would lose that sound entirely
A very simple noise gate would probably do just fine in your situation. Simply wait for the first sample whose amplitude is above a specified threshold value (to avoid triggering with background noise). You would only need to get more complicated than this if you need to distinguish between different types of noise (e.g. a door closing versus a hand clap).

Resources