C++ Levitation is a syntax extension for C++17 standard.
Recently I’ve got a working prototype of first version, with packages implementation.
It’s open source, and I welcome everybody to participate this project!
Find more details on gitlab.
C++ Levitation is a syntax extension for C++17 standard.
Recently I’ve got a working prototype of first version, with packages implementation.
It’s open source, and I welcome everybody to participate this project!
Find more details on gitlab.
I have seen as waves wipe out the footprints on sand.
I have heard as wind sings his song of the weird.
I have heard as trees strings playing this.
The music of waves.
The music of wind.
It’s hard to say here what the asphalt means.
It’s hard to say here what the vehicle means.
You have here to toss the water up.
The music of waves.
The music of wind.
Who of us remember those who stepped out the way?
Who of us remember those who laughed to sang.
Who of us remember feeling the coldness of gun butt…
The music of waves.
The music of wind.
http://ppa.dyatkovskiy.com/raspbian/pool/main/b/bird-osd/bird-osd_1.1.2_armhf.deb
Please read Installation instructions
Hi there! I’m working on text rendering for my small Bird OSD project.
So I want to add contours to the text, so it could be visible whatever background it is rendered on (bright or dark).
For example I want to enhance text rendering for cases like this:
(Ugh… My eyes suffer!)
Into this one:
Assuming we have 1-component color on input which consists only of alpha channel, I want to mark as edge alpha values around 0.5.
Below is my shader which works, and in fact above are screenshots with its demonstraction. It still has some limits though. Edge radius can’t take values ended with .5 due to special rounding case for N*0.5 values. If you use it, and find more issues, please let me know.
// The inpute textures uniform sampler2D uTexture; varying vec2 vTexCoord; // Interpolated texture coordinate per fragment. uniform float uOpacity; uniform float uWidth; uniform float uHeight; // If foreground value is higher than threshold, than edge is zero for this pixel const float NO_EDGE_TRESHOLD = 0.5; // Edge radius, works fine in range from 0.6 to 2.0 // Please don't use N*0.5 values, since it has special rounding rules // and pixel at the left may be in is not the same distance comparing to the right. const float EDGE_RADIUS = 1.; const vec3 EDGE = vec3(0., 0., 0.); // Detects whether we should put edge value in the center. // Not that if the center is foreground value = 1, then there is // no need in edge // (in practice we also admit some values below 1, // determined by threshold). // We work with fonts, not the regular image, so // edge is a function from average of two pixels (not the difference): // f(l, r) = edge((l + r) / 2) // assuming edge should be max, when input value is "k" (belongs to range (0, 1) ) // So, how 'edge' function is defined? // (see picture if formulaes are difficult) // edge(v) = (1./k) * x, if x <= k && x > 0 // otherwise it is line which goes through p1[x,y] = [1, k] and p2[x,y] = [0, 1] // // Y ^ // | p[y=1,x=k] // | /\ // | / \ // |/ \ // -----------> // 0 k 1 X // y=edge(x) formulae // // in case when k = 0.5 then // // f(l, r) = 1 - |l + r - 1| // // Let's use this case! // // params: // left - left foreground value // center - center foreground value // right - right foreground value // returns: // edge value. // float getEdge(float left, float center, float right) { if (center > NO_EDGE_TRESHOLD) return 0.; if (center > left && center > right) return 0.; float ledge = 1. - abs(left + center - 1.); float redge = 1. - abs(right + center - 1.); return max(ledge, redge); } float getNeighbour(float row, float col) { float dx = EDGE_RADIUS / uWidth; float dy = EDGE_RADIUS / uHeight; float texX = clamp(vTexCoord.x + col * dx, 0. + dx/2., 1. - dx/2.); float texY = clamp(vTexCoord.y + row * dy, 0. + dx/2., 1. - dx/2.); return texture2D(uTexture, vec2(texX, texY)).a; } float calcEdge(float centerValue) { // Nighbour pixels: // neighbour[i][j] is neighbour with X = x + (j-1) * DX; Y = y + (i-1) * DY; // neighbour[0][0] is neighbour with X = x - DX; Y = y - DY; float neighbour_0[3]; float neighbour_1[3]; float neighbour_2[3]; for (int j = 0; j != 3; ++j) neighbour_0[j] = getNeighbour(-1., float(j-1)); for (int j = 0; j != 3; ++j) neighbour_1[j] = getNeighbour(0., float(j-1)); for (int j = 0; j != 3; ++j) neighbour_2[j] = getNeighbour(1., float(j-1)); float horEdge = getEdge(neighbour_1[0], centerValue, neighbour_1[2]); float vertEdge = getEdge(neighbour_0[1], centerValue, neighbour_2[1]); float ltrbEdge = getEdge(neighbour_0[0], centerValue, neighbour_2[2]); float rtlbEdge = getEdge(neighbour_0[2], centerValue, neighbour_2[0]); return max( max(horEdge, vertEdge), max(ltrbEdge, rtlbEdge) ); } vec4 calcFinalValue(vec3 foreground, float foregroundValue, float edgeValue) { #if 1 float sumFgEdge = foregroundValue + edgeValue; vec3 color = vec3( foreground * foregroundValue / sumFgEdge + EDGE * edgeValue / sumFgEdge); return vec4(color.r, color.g, color.b, min(sumFgEdge, 1. * uOpacity)); //return vec4(EDGE, edgeValue); #else return vec4(foreground.r, foreground.g, foreground.b, foregroundValue); #endif } // The entry point for our fragment shader. void main() { vec4 texColor = texture2D(uTexture, vTexCoord); float foregroundValue = texColor.a; float edgeValue = calcEdge(foregroundValue); gl_FragColor = calcFinalValue( vec3(texColor.r, texColor.g, texColor.b), foregroundValue, edgeValue ); }
Прошу прощенья у тебя
За то, что ем беспечно плюшки
Чизкейки, пироги, ватружки,
Вкусняшки,
Всякие там кренделя.
И взвешиваться мне каждый раз –
Не нужно.
Жестоко может быть порой –
С тоской
Стыдливою любя
Отжаться двадцать раз отправлю,
И столько же еще присесть,
За пару долек шоколадки,
Что ты успела есть.
И беспощадно но с теплом,
Заставлю сделать пресс раз тридцать.
За блинчик вкусный, что в твоем
Прекрасном теле очутился
Так внезапно!
Запитый рафом с имбирем.
За пищи нетождественный прием –
Скорблю.
Сгорает еда мигом в животе моем,
Я – дрищ (вдобавок малость нервный),
А тебя –
Люблю.
М: Вы кто?
Н: А вы кто?
М: Гм… Здесь что эхо?!
Н: Нет, просто наши голоса похожи, и я вам задал тот же самый вопрос, что и вы мне. Вам показалось.
М: Да это же был сарказм!
Н: Вынужден признать – да – это был сарказм, не смог удержаться, приношу свои извинения.
Однажды мудрец прогуливался по лесу, недалеко от своей деревни, и провалился в яму, вырытую охотниками для большого зверя.
Во время падения он повредил ноги, и потому – не мог выбраться из ямы самостоятельно. Мудрец был стар и слух уже был не тем. Вдобавок яма была глубокой, и он не мог слышать совершенно ничего, что происходит наверху. Он не мог слышать людей проходящих по дороге, что была неподалеку.
“Ну ничего.” – подумал мудрец, – “Меня знают и уважают во всей деревне. Скоро люди хватятся, что меня нет, и пойдут искать.”
Была середина лета, и как раз в эти дни в деревне начался праздник по поводу хорошего урожая пшеницы. Люди танцевали, веселились, влюблялись, словом они и думать забыли о несчастном старце, что постоянно гулял где-то в лесу или горах, а сейчас сидел голодный и покалеченный в яме.
На второй день мудрец понял, что его не скоро спасут, и скорее всего он умрет тут от голода и жажды.
Рядом с ямой рос высокий дуб, ветви которого прикрывали яму от прямых лучей, и спасали сидевшего в ней человека от дневного зноя. И вот на второй день, на высокую ветку, склонявшуюся над ямой прилетела птичка. Ей было очень хорошо, и совсем скоро, она начала петь дивную песню, воспевая, красоту земной природы и нежное тепло утренних лучей солнца.
И вдруг внезапно, птица испугалась и улетела. Мудреца осенило – по дороге идут люди! И он начал что есть силы кидать комки земли как можно выше вверх и кричать. Земля падала обратно ему на голову и на плечи, но он, не смотря ни на что, отчаянно кидал землю вверх и кричал, кричал так громко как только мог!
По дороге шел солдат, который услышал тихий странный вой, и повернув голову в сторону доносящихся звуков – увидел грязь, которая вылетала снизу вверх. Он подошел, и увидел яму, и сидящего в ней несчастного старца.
Солдат спас мудреца, напоил водой, накормил и отвел обратно в деревню.
Если ты в беде, а где-то рядом идет большой праздник и никто про тебя не вспоминает – значит ты никому не нужен. И тебя никто не выручит. Это – горький факт, знание которого, тем не менее – может спасти твою жизнь.
Будь ты хоть семи пядей во лбу, но, сидя в яме, едва ли ты увидешь дальше, чем глупая птичка, которая сидит рядом на дереве.
Бывают обстоятельства в которых не важно мудрец ты или нет. Обстоятельства, в которых от тебя лишь требуется – кидать комки грязи вверх и кричать что есть силы.
Мудрец не знал, что по дороге идет солдат, а солдат не знал ни про яму, ни про то, что в ней сидит именно мудрец. Оба поверили в очевидные и независимые явления: один – в испугавшуюся птицу, другой – в землю, которая летит вверх. Сильный аргумент таков, что не важно – кто именно тебе его преподносит, ты веришь в него исходя из логики и собственных знаний.
И наконец шутка! Если на тебя сверху падает грязь – это не всегда плохо!
You have Raspberry Camera and you need FPV, but you can’t fight 100-200ms latency? Then there is a solution.
Bird OSD turns your Raspberry PI into FPV stream source with OSD overlay.
How?
Since raspberry has Video Composite Output, you can then cast raspberrian screen just like a regular FPV signal over FPV transmitter module!
Raspberry Pi works on broadcomm SoC with VideoCore processor so that means we can apply OSD overlay to camera stream with really low realtime latencies.
Bird OSD is a systemd service, it uses raspivid app to grab camera image, and it uses own bird-osd GLES2 application to apply overlay with sensor data on it.
So finally you should see something like this:
(GPS was broken, sorry, still can’t demonstrate in real fly)
Another pic from FPV goggles:
127.0.0.1:14550
(running ardupilot, arducopter, whatever)Download .deb package onto your raspberry device:
$ wget http://ppa.dyatkovskiy.com/raspbian/pool/main/b/bird-osd/bird-osd_1.1.2_armhf.deb
And then install it:
$ sudo dpkg -i bird-osd_1.1.2_armhf.deb
Then you should target MAVLink channel to 127.0.0.1:14550
E.g. for arducopter:
$ sudo nano /etc/default/arducopter
Ensure you have string like this:
TELEM1="-A udp:127.0.0.1:14550"
Or like this:
TELEM2="-C udp:127.0.0.1:14550"
In case you modified /etc/default/arducopterconfig, then you should restart service:
$ sudo systemctl restart arducopter
Finally you should start bird-osdservice with this command:
sudo systemctl start bird-osd
Then on monitor connected to your raspberryyou should see whatever your camera sees + overlay with sensors data!
It is still very first version:
libraspberrypi-bin (>= 1.20180417-1), bash (>= 4.4-5)
Perhaps dependency versions are higher then it really needs, just had no opportunity to test it on another envs.
If you want to enable bird-osdon boot, you should run:
$ sudo systemctl enable bird-osd
This command disables service:
$ sudo systemctl disable bird-osd
And this command removes bird-osdfrom you raspberry device:
$ dpkg -P bird-osd
Edge detection for text – simple edge detection shader for text-like foreground drawings
I just put it here:
sudo killall -HUP mDNSResponder
Let’s imagine that humanity died out, and new civilzation discovered that human beings used puffer jackets to save body heat.
But they didn’t know how it works. So they “disassembled” one of jackets they found, and discovered that it consists of bird fluff.
And this is how they reproduced heat saver thing. They made a building with walls out of fluffs cemented with clay. And got little progress. So they tried to use glair instead of clay, but still too bad.
Only 128 years later, when they advanced on heat theory, they understood what was wrong, and made building with hollow walls, but filled with flair.
A bit later knowing theory and learned chemistry and gas dynamics they stopped to kill birds, and replaced flair with synthetic heat insulation fiber.
Well, if we advance on how our mind works, we perhaps find a better use of artificial neural networks, or may be replace it with better concept?