What happens if i set 'raspicam_node/image' queue size to 1? - raspberry-pi

I can't get real-time image from raspberry pi cam.
So I adjusted the Queue Size from 100 to 1.
Then there was an improvement in performance.
I wonder why there was a performance improvement.
int main(int argc, char** argv)
{
ros::init(argc, argv, "lane_driving");
ros::NodeHandle nh, nhp;
image_transport::ImageTransport it(nh);
pub = nhp.advertise<geometry_msgs::Twist>("/cmd_vel", 100);
subAD = nh.subscribe("arrowDetecter", 1,&arrowMessage);
subScan = nh.subscribe("/scan",1,&scanMsgCallback);
subOdom = nh.subscribe("/odom", 1,&odomMsgCallback);
image_transport::Subscriber sub = it.subscribe("/raspicam_node/image", 1, &poseMessageReceived, ros::VoidPtr(), image_transport::TransportHints("compressed"));
while(ros::ok()){
baseCmd.linear.x = 0.01;
pub.publish(baseCmd);
ros::spin();
}

If the number of messages that arrive on the /raspicam_node/image topics in a single ros::spin() is greater than the queue_size, the extra messages will be discarded. What this means is that your callback is probably not running for every image that comes from your camera. So you are probably "dropping" (not analyzing) some of the camera frames. This would give the performance improvement you observed.
Whether or not this is what you want depends on your application.

Related

schedule the starting time of events as accurately as possible

I would like to schedule a series of events such that to about the nearest 5ms, the starting time of event N is t0 + dt*N, where t0 is some arbitrary time after the process starts. If the events were output to a terminal, they would occur regularly without pauses or speedups. If they were noises, it would produce a regular rhythm. This is my first attempt.
#include <stdio.h>
#include <time.h>
#include <math.h>
void fsleep(double t)
{
time_t sec = floor(t);
long nsec = 1e9*(t - sec);
struct timespec s;
s.tv_sec = sec;
s.tv_nsec = nsec;
nanosleep(&s, NULL);
}
int main(int argc, const char **argv)
{
for (unsigned i = 0;; i++) {
printf("%d\n", i);
fflush(stdout);
fsleep(0.334);
}
}
It is total garbage, even at realtime priority (nice -n -20). There are noticeable jitters the entire time, with pauses of up to 1 second, after which a whole bunch of numbers are printed in a row. To test whether it was my terminal, I made the following script:
from time import sleep
from sys import stdin
def raw_stdin():
"""Switches stdin to a non-buffering, non-echoing mode,
handing keystrokes directly to the program as soon as they're
received and printing nothing to the terminal."""
import termios as t
f = t.tcgetattr(stdin)
f[3] &= ~(t.ICANON|t.ECHO)
t.tcsetattr(stdin, t.TCSANOW, f)
raw_stdin()
for i in range(10000000):
#sleep(.334)
stdin.read(1)
print(i)
If I hit any key regularly, i.e. with the same time intervals between strokes down to the nearest 10ms or so, I get regular outputs, with zero hesitations. This proves the terminal is more than responsive enough, and that what I'm trying to do is possible. I have a hard time imagining the computer can't do something I can do with my left index finger.
I think it might have something to do with my linux kernel. I'd be interested to know what happens if this is run in windows, or on other linux kernels.
I figured it out. It was my terminal all along (xfce4-terminal). There's a bug in it that messes up realtime output. See https://stackoverflow.com/a/47744798/1840698 for more.

MSP430 Music Player Can't Produce Note Higher than Certain Frequency

I'm trying to complete an assignment that requires me to make a music player using the MSP430 microprocessor and Launchpad kit. I have the player completely working, but for some reason when I try to play above a certain note, it outputs rapid clicking instead of the tone.
I know the speaker can produce a higher tone, so I am fairly certain it's an issue with my software, probably creating some sort of math error. Here is my code (at least the part that handles the notes):
asm(" .length 10000");
asm(" .width 132");
#include "msp430g2553.h"
//-----------------------
// define the bit mask (within P1) corresponding to output TA0
#define TA0_BIT 0x02
// define the port and location for the button (this is the built in button)
// specific bit for the button
#define BUTTON_BIT 0x04
#define PLUS_BUTTON 0x08 //Defines the "GO FASTER" button to P1.3
#define MINUS_BUTTON 0x10 //Defines the "SLOW DOWN" button to P1.4
#define SHIFT 0x20
//----------------------------------
// Some global variables (mainly to look at in the debugger)
volatile unsigned halfPeriod; // half period count for the timer
volatile unsigned long intcount=0; // number of times the interrupt has occurred
volatile unsigned soundOn=0; // state of sound: 0 or OUTMOD_4 (0x0080)
volatile int noteCount = 0;
volatile int noteLength = 0;
volatile int deltaHP=1; // step in half period per half period
volatile unsigned int plus_on;
volatile unsigned int minus_on;
volatile double speed = 1;
volatile int shiftkey = 0;
static const int noteArray[] = {800, 1000, 900, 800}; //THESE ARE THE NOTES
static const int noteLengths[] = {200, 500, 500, 500};
void init_timer(void); // routine to setup the timer
void init_button(void); // routine to setup the button
// ++++++++++++++++++++++++++
void main(){
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_1MHZ; // 1Mhz calibration for clock
DCOCTL = CALDCO_1MHZ;
//halfPeriod=noteArray[0]; // initial half-period at lowest frequency
init_timer(); // initialize timer
init_button(); // initialize the button
_bis_SR_register(GIE+LPM0_bits);// enable general interrupts and power down CPU
}
// +++++++++++++++++++++++++++
// Sound Production System
void init_timer(){ // initialization and start of timer
TA0CTL |=TACLR; // reset clock
TA0CTL =TASSEL1+ID_0+MC_2; // clock source = SMCLK, clock divider=1, continuous mode,
TA0CCTL0=soundOn+CCIE; // compare mode, outmod=sound, interrupt CCR1 on
TA0CCR0 = TAR+noteArray[0]; // time for first alarm
P1SEL|=TA0_BIT; // connect timer output to pin
P1DIR|=TA0_BIT;
}
// +++++++++++++++++++++++++++
void interrupt sound_handler(){
TACCR0 += (noteArray[noteCount]); // advance 'alarm' time
if (soundOn){ // change half period if the sound is playing
noteLength++;
if (noteLength >= (speed* noteLengths[noteCount])) {
noteLength=0;
noteCount++;
if (noteCount == sizeof(noteArray)/sizeof(int)) {
//halfPeriod += deltaHP;
noteCount = 0;
//deltaHP=-deltaHP;
}
}
}
TA0CCTL0 = CCIE + soundOn; // update control register with current soundOn
++intcount; // advance debug counter
}
ISR_VECTOR(sound_handler,".int09") // declare interrupt vector
Currently I have just 4 random notes in there with 4 random lengths to demonstrate the error. The strange clicking noise happens somewhere between a note value of 800 and 900. Am I just missing something in my code that would produce an error for a number smaller than 8xx? I don't see any spots for division errors or the like but I could be wrong.
Thank you.
ALSO: I should note that when the error occurs, the clicking lasts a very long time, much longer than the corresponding length for that note, but it isn't permanent. Eventually the player moves on to the next note and plays it normally as long as it's larger than 900 or so.
If the interrupt handler does not execute fast enough, the setting of the next event (TACCR0 += noteArray[...]) will come too late, i.e., after that timer value has already been reached. So the next timer interrupt will fire not after 800 ticks but after 216+800 ticks.
You might try to optimize the interrup handler function.
In particular, floating-point emulation can take hundreds of cycles; remove speed.
However, instead of toggling the output in software, you should take advantage of the hardware capabilites, and generate the waveform with the PWM function: run the timer in Up mode, and use set/reset output mode for the second CCR (see section 12.2.5.2 of the User's Guide).
(This implies that you need timer interrupts only to start/stop notes, so to fit into the 216 limit, you probably want to use a second timer based on a much slower clock.)

Observable to simulate high frequency signal

I have a server that receives batches of signal samples from clients. Each batch can contain up to 1000 samples and be received once per second (1000 Hz). Once I have received the samples, I want to publish them locally via an Observable at the same frequency they were generated from the signal source device. I have put together the following concept code that accomplishes what I want to do.
LINQPad code:
var frequency = 1000; // samples / second
int sampleCount = 1000;
var samples = Enumerable.Range(1, sampleCount).ToArray();
ManualResetEvent done = new ManualResetEvent(false);
int count = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
samples.ToObservable()
.Do(_ => Thread.Sleep(1000/frequency))
.Subscribe((next) => count++, () => { sw.Stop(); done.Set(); });
done.WaitOne();
sw.ElapsedMilliseconds.Dump("Subscription duration");
count.Dump("Items observed");
I tried other ways to simulate the delay between samples, but at such high frequencies, any timer-based or task-based approaches apparently had too much overhead to keep up. So my question(s) are:
Is this the best approach to delaying a high frequency observable?
In the Do(...) method, it is the 'SubscribeOn' thread that I am putting to sleep, right?
Should I explicitly be calling the SubscribeOn() and ObserveOn() method to help ensure that the observer code does not interfere with publishing of the samples?
Thanks in advance!

FANN: How do I find a balance between the desired error and the bit fail?

I want the network to stop training when the bit fail is 0.
When that normally happens, the desired error is pretty low. But If I set the desired error too low, the network will keep training.. even over training even if the bit fail is 0....
How to I find a good balance between desired error and bit fail?
TL;DR: How do I calculate the lowest possible desired error such that the network stops training when the bit fail reaches 0?
You can create a method of type fann_callback_type, let's call it trainCallback and then set this method as a callback to your NN (using the fann_set_callback method)
This method - trainingCallback - will be called while training, instead of printing out details of the training.
In this callback you have access to all the information you need (MSE, bitfail etc. - check out the signature at the links above) and if you return a value smaller than 0, than the training will stop.
Hope it helps
int trainCallback(struct fann *ann, struct fann_train_data *train,
unsigned intmax_epochs, unsigned int epochs_between_reports,
float desired_error, unsigned int epochs) {
if(/*your condition*/)
return -1;
return 0;
}
/* in your code */
{
...
fann_set_callback(ptrToFANN, &trainCallback);
...
}

iPhone audio analysis

I'm looking into developing an iPhone app that will potentially involve a "simple" analysis of audio it is receiving from the standard phone mic. Specifically, I am interested in the highs and lows the mic pics up, and really everything in between is irrelevant to me. Is there an app that does this already (just so I can see what its capable of)? And where should I look to get started on such code? Thanks for your help.
Look in the Audio Queue framework. This is what I use to get a high water mark:
AudioQueueRef audioQueue; // Imagine this is correctly set up
UInt32 dataSize = sizeof(AudioQueueLevelMeterState) * recordFormat.mChannelsPerFrame;
AudioQueueLevelMeterState *levels = (AudioQueueLevelMeterState*)malloc(dataSize);
float channelAvg = 0;
OSStatus rc = AudioQueueGetProperty(audioQueue, kAudioQueueProperty_CurrentLevelMeter, levels, &dataSize);
if (rc) {
NSLog(#"AudioQueueGetProperty(CurrentLevelMeter) returned %#", rc);
} else {
for (int i = 0; i < recordFormat.mChannelsPerFrame; i++) {
channelAvg += levels[i].mPeakPower;
}
}
free(levels);
// This works because one channel always has an mAveragePower of 0.
return channelAvg;
You can get peak power in either dB Free Scale (with kAudioQueueProperty_CurrentLevelMeterDB) or simply as a float in the interval [0.0, 1.0] (with kAudioQueueProperty_CurrentLevelMeter).
Don't forget to activate level metering for AudioQueue first:
UInt32 d = 1;
OSStatus status = AudioQueueSetProperty(mQueue, kAudioQueueProperty_EnableLevelMetering, &d, sizeof(UInt32));
Check the 'SpeakHere' sample code. it will show you how to record audio using the AudioQueue API. It also contains some code to analyze the audio realtime to show a level meter.
You might actually be able to use most of that level meter code to respond to 'highs' and 'lows'.
The AurioTouch example code performs Fourier analysis
on the mic input. Could be a good starting point:
https://developer.apple.com/iPhone/library/samplecode/aurioTouch/index.html
Probably overkill for your application.