Low FPS and freeze while streaming high resolution cameras with opencv - opencv

I've recently purchased a new camera that is capable of streaming 60fps on HD resolution.
while using the most basic gst-launch-1.0 line : gst-launch-1.0 v4l2src ! xvimagesink it opens the camera on high res with high FPS with no lag and no freezing.
However, when trying to start the camera on opencv VideoCapture module, anything above 640x480 freezes a lot and gives very low FPS.
My best guess is that my pipelines are not ideal and I am not running the camera as intended on HW accelerated pipeline, but rather eating up my CPU which can't handle the stream, as well as running on an uncompressed format UYVY.
A few pipelines examples that i've tried:
cv2.VideoCapture('v4l2src device=/dev/video0 ! video/x-raw,width=1920,height=1080! nvvidconv flip-method=2 ! video/x-raw(memory:NVMM), format=I420! nvvidconv ! video/x-raw, format=BGRx , width=1920, height=1080, framerate=60/1 ! videoconvert ! video/x-raw, format=BGR ! appsink drop=True sync=False')
cv2.VideoCapture('v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, format=BGR ! appsink')
I am running on Jetson Xavier NX.
Would appreciate any help and examples of better pipelines, I haven't found many v4l2src examples if any and non worked well for me.
i should add basic camera information from gst-device-monitor-1.0 :
Device found:
name : See3CAM_CU30
class : Video/Source
caps : video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 12/1 };
video/x-raw, format=(string)UYVY, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 42/1, 21/1 };
video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 15/1 };
video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 50/1, 25/1 };
video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1, 15/1 };
video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 58/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
image/jpeg, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)48/1;
image/jpeg, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
image/jpeg, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
image/jpeg, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)58/1;
image/jpeg, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
properties:
udev-probed = true
device.bus_path = platform-3610000.xhci-usb-0:3.4:1.0
sysfs.path = /sys/devices/3610000.xhci/usb2/2-3/2-3.4/2-3.4:1.0/video4linux/video0
device.bus = usb
device.subsystem = video4linux
device.vendor.id = 2560
device.vendor.name = "e-con\\x20systems"
device.product.id = c130
device.product.name = See3CAM_CU30
device.serial = e-con_systems_See3CAM_CU30_152B9904
device.capabilities = :capture:
device.api = v4l2
device.path = /dev/video0
v4l2.device.driver = uvcvideo
v4l2.device.card = See3CAM_CU30
v4l2.device.bus_info = usb-3610000.xhci-3.4
v4l2.device.version = 264701 (0x000409fd)
v4l2.device.capabilities = 2216689665 (0x84200001)
v4l2.device.device_caps = 69206017 (0x04200001)
gst-launch-1.0 v4l2src ! ...

Related

ffmpeg conversion: Twitter rejects video with "Not valid video"

I have an app that uploads via twitter api chunked upload, and it finally works with photos.
However, I am trying to get it to work with videos.
Uploading didnt work out-of-the-box even though the video format is mp4. The twitter guidelines for uploads are these
With that in mind, I have this ffmpeg command so far:
ffmpeg -i in.mp4 -vf \"scale=1280:720\" -b:v 5000K -minrate 5000K -maxrate 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -profile:v high -pix_fmt yuv420p -strict -2 -ac 2 -acodec aac out.mp4
I still get "Not valid video", and I don't know why.
Here's my mediainfo output for out.mp4:
General
Count : 328
Count of stream of this kind : 1
Kind of stream : General
Kind of stream : General
Stream identifier : 0
Count of video streams : 1
Count of audio streams : 1
Video_Format_List : AVC
Video_Format_WithHint_List : AVC
Codecs Video : AVC
Video_Language_List : English
Audio_Format_List : AAC
Audio_Format_WithHint_List : AAC
Audio codecs : AAC LC
Audio_Language_List : English
Complete name : video-5e4405cd4348a5e4405cd434d2.mp4
File name : video-5e4405cd4348a5e4405cd434d2
File extension : mp4
Format : MPEG-4
Format : MPEG-4
Format/Extensions usually used : mov mp4 m4v m4a m4b m4p 3ga 3gpa 3gpp 3gp 3gpp2 3g2 k3g jpm jpx mqv ismv isma ismt f4a f4b f4v
Commercial name : MPEG-4
Format profile : Base Media
Internet media type : video/mp4
Codec ID : isom
Codec ID : isom (isom/iso2/avc1/mp41)
Codec ID/Url : http://www.apple.com/quicktime/download/standalone.html
CodecID_Compatible : isom/iso2/avc1/mp41
Codec : MPEG-4
Codec : MPEG-4
Codec/Extensions usually used : mov mp4 m4v m4a m4b m4p 3ga 3gpa 3gpp 3gp 3gpp2 3g2 k3g jpm jpx mqv ismv isma ismt f4a f4b f4v
File size : 52664272
File size : 50.2 MiB
File size : 50 MiB
File size : 50 MiB
File size : 50.2 MiB
File size : 50.22 MiB
Duration : 79744
Duration : 1 min 19 s
Duration : 1 min 19 s 744 ms
Duration : 1 min 19 s
Duration : 00:01:19.744
Duration : 00:01:19:20
Duration : 00:01:19.744 (00:01:19:20)
Overall bit rate : 5283334
Overall bit rate : 5 283 kb/s
Frame rate : 30.000
Frame rate : 30.000 FPS
Frame count : 2390
Stream size : 88780
Stream size : 86.7 KiB (0%)
Stream size : 87 KiB
Stream size : 87 KiB
Stream size : 86.7 KiB
Stream size : 86.70 KiB
Stream size : 86.7 KiB (0%)
Proportion of this stream : 0.00169
HeaderSize : 40
DataSize : 52575500
FooterSize : 88732
IsStreamable : No
File last modification date : UTC 2020-02-12 14:05:37
File last modification date (local) : 2020-02-12 15:05:37
Writing application : Lavf57.83.100
Writing application : Lavf57.83.100
Video
Count : 342
Count of stream of this kind : 1
Kind of stream : Video
Kind of stream : Video
Stream identifier : 0
StreamOrder : 0
ID : 1
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format/Url : http://developers.videolan.org/x264.html
Commercial name : AVC
Format profile : High#L3.1
Format settings : CABAC / 4 Ref Frames
Format settings, CABAC : Yes
Format settings, CABAC : Yes
Format settings, ReFrames : 4
Format settings, ReFrames : 4 frames
Internet media type : video/H264
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Codec : AVC
Codec : AVC
Codec/Family : AVC
Codec/Info : Advanced Video Codec
Codec/Url : http://developers.videolan.org/x264.html
Codec/CC : avc1
Codec profile : High#L3.1
Codec settings : CABAC / 4 Ref Frames
Codec settings, CABAC : Yes
Codec_Settings_RefFrames : 4
Duration : 79667
Duration : 1 min 19 s
Duration : 1 min 19 s 667 ms
Duration : 1 min 19 s
Duration : 00:01:19.667
Duration : 00:01:19:20
Duration : 00:01:19.667 (00:01:19:20)
Bit rate : 5000000
Bit rate : 5 000 kb/s
Width : 1280
Width : 1 280 pixels
Height : 720
Height : 720 pixels
Sampled_Width : 1280
Sampled_Height : 720
Pixel aspect ratio : 1.000
Display aspect ratio : 1.778
Display aspect ratio : 16:9
Rotation : 0.000
Frame rate mode : CFR
Frame rate mode : Constant
FrameRate_Mode_Original : VFR
Frame rate : 30.000
Frame rate : 30.000 FPS
Frame count : 2390
Resolution : 8
Resolution : 8 bits
Colorimetry : 4:2:0
Color space : YUV
Chroma subsampling : 4:2:0
Chroma subsampling : 4:2:0
Bit depth : 8
Bit depth : 8 bits
Scan type : Progressive
Scan type : Progressive
Interlacement : PPF
Interlacement : Progressive
Bits/(Pixel*Frame) : 0.181
Stream size : 51297022
Stream size : 48.9 MiB (97%)
Stream size : 49 MiB
Stream size : 49 MiB
Stream size : 48.9 MiB
Stream size : 48.92 MiB
Stream size : 48.9 MiB (97%)
Proportion of this stream : 0.97404
Writing library : x264 - core 152 r2854 e9a5903
Writing library : x264 core 152 r2854 e9a5903
Encoded_Library_Name : x264
Encoded_Library_Version : core 152 r2854 e9a5903
Encoding settings : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=12 / lookahead_threads=2 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=5000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Language : en
Language : English
Language : English
Language : en
Language : eng
Language : en
Audio
Count : 275
Count of stream of this kind : 1
Kind of stream : Audio
Kind of stream : Audio
Stream identifier : 0
StreamOrder : 1
ID : 2
ID : 2
Format : AAC
Format/Info : Advanced Audio Codec
Commercial name : AAC
Format profile : LC
Format settings, SBR : No (Explicit)
Format settings, SBR : No (Explicit)
Codec ID : mp4a-40-2
Codec : AAC LC
Codec : AAC LC
Codec/Family : AAC
Codec/CC : 40
Duration : 79744
Duration : 1 min 19 s
Duration : 1 min 19 s 744 ms
Duration : 1 min 19 s
Duration : 00:01:19.744
Duration : 00:01:19:25
Duration : 00:01:19.744 (00:01:19:25)
Bit rate mode : CBR
Bit rate mode : Constant
Bit rate : 128257
Bit rate : 128 kb/s
Channel(s) : 2
Channel(s) : 2 channels
Channel positions : Front: L R
Channel positions : 2/0/0
ChannelLayout : L R
Samples per frame : 1024
Sampling rate : 48000
Sampling rate : 48.0 kHz
Samples count : 3827712
Frame rate : 46.875
Frame rate : 46.875 FPS (1024 SPF)
Frame count : 3738
Compression mode : Lossy
Compression mode : Lossy
Stream size : 1278470
Stream size : 1.22 MiB (2%)
Stream size : 1 MiB
Stream size : 1.2 MiB
Stream size : 1.22 MiB
Stream size : 1.219 MiB
Stream size : 1.22 MiB (2%)
Proportion of this stream : 0.02428
Language : en
Language : English
Language : English
Language : en
Language : eng
Language : en
Default : Yes
Default : Yes
Alternate group : 1
Alternate group : 1
Edit: Guess Ill add my PHP code too (This is chopped in a sensible manner because the actual file is very large):
// Set up Codebird
\Codebird\Codebird::setConsumerKey($consumer_key, $consumer_secret); // static, see README
$cb = \Codebird\Codebird::getInstance();
$cb->setToken($token, $token_secret);
$cb->setTimeout(60 * 1000); // 60 second request timeout
$video = new Video($path);
// Convert to the parameter required by twitter.
$converted = $video->convert();
$path = realpath('videos/' . $converted);
$file = fopen($path, 'rb');
$size = fstat($file)['size'];
$mime_type = mime_content_type($path);
$media = $cb->media_upload([
'command' => 'INIT',
'media_type' => $mime_type,
'media_category' => 'tweet_video',
'total_bytes' => $size,
]);
$success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx
if (!$success) {
throw new TwitterException("Failed to INIT upload for $path...");
}
// APPEND chunks to upload.
$mediaId = $media->media_id_string;
$segmentId = 0;
while (!feof($file)) {
echo "chunk #$segmentId....";
$chunk = fread($file, 512 * 1024); // caps out at 512 MB
echo "chunk size: ". strlen($chunk);
$media = $cb->media_upload([
'command' => 'APPEND',
'media_id' => $mediaId,
'segment_index' => $segmentId,
'media' => $chunk,
]);
$success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx
if (!$success) {
throw new TwitterException("Failed to APPEND to upload for $path, chunk $segmentId...");
}
$segmentId++;
}
// Close file and FINALIZE upload.
fclose($file);
echo "FINALIZING id $mediaId...";
$media = $cb->media_upload([
'command' => 'FINALIZE',
'media_id' => $mediaId,
]);
$success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx
if (!$success) {
var_dump($media);
throw new TwitterException("Failed to FINALIZE upload for $path...");
}
return $mediaId;
Video is my ffmpeg class, which I'll paste below, and $path is a URL leading to a perfectly valid mp4 video.
Video.php:
<?php
class VideoConversionException extends \Exception {}
class Video {
public $name;
public $converted;
public function __construct($name) {
self::clear();
$this->name = $name;
}
public function convert() {
$tmpVideo = 'video-' . uniqid() . uniqid() . '.mp4';
$videoPath = 'videos/' . $tmpVideo;
//$ffmpeg = "ffmpeg -i https://tvcanarias.acfipress.com/BC_190907_gc_teror.mp4 -vf "scale=1280:720" -b:v 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -acodec aac output_video.mp4";
$ffmpeg = "ffmpeg -i {$this->name} -vf \"scale=1280:720\" -b:v 5000K -minrate 5000K -maxrate 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -profile:v high -pix_fmt yuv420p -strict -2 -ac 2 -acodec aac $videoPath";
//$ffmpeg = "ffmpeg -i {$this->name} -pix_fmt yuv420p -vcodec libx264 -vf scale=640:-1 -acodec aac -vb 1024k -minrate 1024k -maxrate 1024k -bufsize 1024k -ar 44100 -ac 2 -strict experimental -r 30 $videoPath";
$output = [];
exec($ffmpeg, $output, $status);
if ($status != 0) {
//die("Couldnt run ffmpeg. (Error code: #$status)");
throw new VideoConversionException("Couldn't run ffmpeg. (Error code: #$status)");
}
$this->converted = $tmpVideo;
return $tmpVideo;
}
public function shredConverted() {
// delete video.
#unlink("videos/{$this->$converted}");
}
public static function clear() {
// We can't really shred videos right away as they might be still uploading.
// Therefore, every time this library is used, we will just delete videos older
// than, say, an hour.
$files = scandir('videos');
$curtime = time();
foreach ($files as $file) {
if ($file == '.gitignore' || $file == '.' || $file == '..') {
continue;
}
$mtime = filemtime("videos/$file");
$diff = $curtime - $mtime;
$overAnHour = $diff > (60 * 60);
if ($overAnHour) {
#unlink("videos/$file");
}
}
}
}

How to make Erlang client/server connect with arguments/nodes from config?

I'm writing a client/server System in Erlang and can't get them to connect. The nodes they should use are stored in config files, which are loaded upon starting them. They also use several distributed data structures. Problem is, I'm first starting the data structure, then the server (works fine) but when I start the client, it doesn't connect to anything and throws an exception.
Server:
-module(server).
-export([startServer/0,loopServer/7,node/0,log/0,name/0]).
-compile({no_auto_import,[node/0]}).
-import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2]).
-import(erlang, [append/2]).
log() ->
erlang:list_to_atom(lists:concat(["Server#", node(),".log"])).
node() ->
{ok,Config} = file:consult("configs/server.cfg"),
{ok, Node} = werkzeug:get_config_value(node,Config),
Node.
name() ->
{ok,Config} = file:consult("configs/server.cfg"),
{ok, Name} = werkzeug:get_config_value(servername,Config),
Name.
%%Startet den Server und die darin enthaltene Schleife
startServer() ->
{ok,Config} = file:consult("configs/server.cfg"),
{ok, Name} = get_config_value(servername,Config),
%%CMEM initialisieren
{ok, RemTime} = get_config_value(cmemtime,Config),
CMEM = cmem:initCMEM(RemTime, log()),
%%HBQ-Prozess erzeugen
{ok,HBQName} = get_config_value(hbqname,Config),
{ok,HBQNode} = get_config_value(node,Config),
HBQ = {HBQName,HBQNode},
{ok,Serverzeit} = get_config_value(serverzeit,Config),
%%Zeitpunkt des Timer übergeben
{ok, Timer} = timer:send_after(round(RemTime * 1000),Name,delServer),
%%Prozess registrieren, Serverschleife mit allen Infos starten, plus NNr 1
ServerPid = spawn(?MODULE, loopServer, [Name,CMEM,HBQ,Timer,Serverzeit,Config,1]),
register(Name,ServerPid),
%%HBQ initialisieren
HBQ ! {ServerPid, {request,initHBQ}},
{Config,CMEM,HBQ,ServerPid}.
loopServer(Name,CMEM,HBQ,Timer,Serverzeit,Config,NNr) ->
receive
%%Client fragt neue Nachrichten ab, dazu wird aus CMEM die aktuelle NNr für
%%den Client angefordert und mit der ClientPID an die HBQ weitergegeben
{ClientPID,getmessages} ->
NewTimer = reset_timer(Timer,Serverzeit,delServer),
ClientNNr = cmem:getClientNNr(CMEM, ClientPID),
HBQ ! {self(), {request, deliverMSG, ClientNNr, ClientPID}},
logging(log(), lists:concat(["Server: Nachricht ", NNr, " wurde zugestellt.\n"])),
loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr);
%%Nachricht soll in HBQ verschoben werden
{dropmessage,[INNr,Msg,TSclientout]} ->
NewTimer = reset_timer(Timer,Serverzeit,delServer),
HBQ ! {self(), {request,pushHBQ,[INNr,Msg,TSclientout]}},
receive
{reply,ok} ->
logging(log(), lists:concat(["Server: Nachricht ", INNr, " wurde in HBQ eingefuegt.\n"]))
end,
loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr);
%%Client fragt naechste NNr ab, diese wird dem Zustand des Server entnommen
{ClientPID,getmsgid} ->
NewTimer = reset_timer(Timer,Serverzeit,delServer),
ClientPID ! {nid, NNr},
NewNNr = NNr + 1,
logging(log(), lists:concat(["Server: Nachrichtennumer ", NNr, " an ", erlang:pid_to_list(ClientPID), "gesendet.\n"])),
loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NewNNr);
%%Server beendet sich selbst und zugleich die HBQ
delServer ->
HBQ ! {self(),{request,delHBQ}},
receive
{reply,ok} ->
logging(log(), lists:concat([lists:concat(["Server: Downtime ", werkzeug:timeMilliSecond(), " von ", name() ,"\n"])])),
ok
end
end.
Client:
-module(client).
-export([startClients/0,loopClient/4,spawnC/1,forLoop/3,mitServerVerbinden/6,configLaden/0]).
-import(werkzeug, [get_config_value/2]).
-import(timer, [apply_after/4]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Client %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%initClient
startClients() ->
Config = configLaden(),
{ok, ClientAnzahl} = werkzeug:get_config_value(clientanzahl, Config),
{ok, ServerName} = werkzeug:get_config_value(servername, Config),
{ok, ServerNode} = werkzeug:get_config_value(servernode, Config),
ServerPid = {ServerName,ServerNode},
forLoop(ClientAnzahl, fun client:spawnC/1, ServerPid).
%%Hilfsfunktion fuer for-Schleife: Zaehlt runter,
%%ruft Funktion auf und gibt Ergebnisse als Liste zurueck
forLoop(Clients, Spawn, SPid) -> forLoop(Clients, Spawn, SPid, []).
forLoop(0, _Spawn, _SPid, ClientListe) -> ClientListe;
forLoop(Clients, Spawn, SPid, ClientListe) ->
ClientListeNew = ClientListe ++ [Spawn(SPid)],
ClientsNew = Clients - 1,
forLoop(ClientsNew, Spawn, SPid, ClientListeNew).
%%Neuen ClientProzess erzeugen
spawnC(ServerPid) ->
Config = configLaden(),
{ok, Lebenszeit} = werkzeug:get_config_value(lebenszeit, Config),
{ok, Cookie} = werkzeug:get_config_value(cookie, Config),
{ok, ServerNode} = werkzeug:get_config_value(servernode, Config),
{ok, Wartezeit} = werkzeug:get_config_value(wartezeit, Config),
ClientPid = erlang:spawn(?MODULE, mitServerVerbinden, [ServerPid, [], [], Wartezeit, ServerNode, Cookie]),
timer:kill_after(Lebenszeit, ClientPid),
ClientPid.
%%mit Server Verbinden
mitServerVerbinden(ServerPid,Datei,NNummern,Wartezeit,ServerNode,Cookie) ->
erlang:set_cookie(ServerNode,Cookie),
pong = net_adm:ping(ServerNode),
loopClient(ServerPid,NNummern,Wartezeit,Datei).
%%loopClient
loopClient(ServerPid,NNummern,Wartezeit,Datei) ->
%%Client wird zum Redakteur
{NNummernNew, WartezeitNew, DateiNew} = nachrichtenSenden(5,ServerPid,NNummern,Wartezeit,Datei),
%%Client wird zum Leser
nachrichtenLesen(false, NNummernNew, ServerPid,DateiNew),
%%Methode ruft sich selbst wieder auf
loopClient(ServerPid, NNummernNew, WartezeitNew,DateiNew).
configLaden() ->
{ok, Config} = file:consult("configs/client.cfg"),
Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Redakteur %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%Nachricht soll vergessen werden
nachrichtenSenden(0,ServerPid,NNummern,Wartezeit,Datei) ->
%%Naechste NNr beim Server anfragen
ServerPid ! {self(),getmsgid},
receive
%%Server sendet NNr
{nid,NNr} ->
%%Logeintrag
werkzeug:logging(Datei,lists:concat([NNr, "te Nachricht um ", werkzeug:timeMilliSecond(), " vergessen zu senden. ******\n"]))
end,
WartezeitNew = wartezeitBerechnen(Wartezeit),
%%Rückgabewerte: Liste mit Nachrichtennummern fuer leser, neue Wartezeit, Logfile
{NNummern,WartezeitNew,Datei};
%%Nachrichtennummer anfragen und erhalten, Nachricht schreiben
nachrichtenSenden(NachrichtenVorVergessen,ServerPid,NNummern,Wartezeit,Datei) ->
Config = configLaden(),
{ok, ServerNode} = werkzeug:get_config_value(servernode, Config),
%%Naechste NNr beim Server anfragen
ServerPid ! {self(),getmsgid},
receive
%%Server sendet NNr
{nid,NNr} ->
%%Nachricht schreiben
Nachricht = nachrichtSchreiben(NNr),
%%NNr zur Liste hinzufuegen fuer Leser
NNummernNew = NNummern ++[NNr],
timer:sleep(Wartezeit),
%%Nachricht an Server senden
ServerPid ! {dropmessage,[NNr,Nachricht,erlang:now()]},
%%Logeintrag schreiben
werkzeug:logging(Datei,lists:concat([Nachricht, " gesendet"])),
%%Neue Wartezeit berechnen
WartezeitNew = wartezeitBerechnen(Wartezeit),
%%Zaehler dekrementieren
NachrichtenVorVergessenNew = NachrichtenVorVergessen -1,
%%Methode neu aufrufen
nachrichtenSenden(ServerPid,NNummernNew,WartezeitNew,NachrichtenVorVergessenNew,Datei)
end.
%%nachrichtSchreiben
nachrichtSchreiben(NNr) ->
Config = configLaden(),
{ok, Rechner} = werkzeug:get_config_value(rechner, Config),
{ok, Praktikumsgruppe} = werkzeug:get_config_value(praktikumsgruppe, Config),
{ok, Teamnummer} = werkzeug:get_config_value(teamnummer, Config),
lists:concat(["client#",Rechner, "_", Praktikumsgruppe, "_", Teamnummer, ": ", integer_to_list(NNr), "_te Nachricht. Sendezeit: ", werkzeug:timeMilliSecond()]).
%%Hilfsmethode: Intervall darf nicht kleiner als zwei Sekunden werden
minimumTime() -> 2000.
%%Berechnet das neue Zeitintervall, um die Haelfte groesser oder
%%kleiner als die alte Zeit, solange sie groesser gleich 2 Sekunden ist
wartezeitBerechnen(Wartezeit) ->
GroesserKleiner = werkzeug:bool_rand(),
HaelfteZeit = trunc(max(Wartezeit * 0.5, minimumTime())),
if
GroesserKleiner ->
Wartezeit + HaelfteZeit;
true ->
max(Wartezeit - HaelfteZeit, minimumTime())
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Leser %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nachrichtenLesen(true,NNummern,ServerPid,Datei) -> ok;
nachrichtenLesen(false,NNummern,ServerPid,Datei) ->
ServerPid ! {self(),getmessages},
receive
{reply,Message,Terminated} ->
nachrichtInLogSchreiben(Message,NNummern,Datei),
nachrichtenLesen(Terminated,NNummern,ServerPid,Datei)
end.
nachrichtInLogSchreiben([NNr,Msg,TSclientout,TShbqin,TSdlqin,TSdlqout],NNummern,Datei) ->
Now = erlang:timestamp(),
DLQInTrue = werkzeug:validTS(TSdlqin),
DLQOutTrue = werkzeug:validTS(TSdlqout),
DLQInZukunft = werkzeug:lessTS(Now, TSdlqin),
DLQOutZukunft = werkzeug:lessTS(Now, TSdlqout),
MsgVonGleichemClient = msgVonGleichemClient(NNr, Msg, NNummern),
if
DLQInTrue and DLQInZukunft ->
Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqin, Now)),
MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied,
werkzeug:logging(Datei, MsgNew ++ "\n");
DLQOutTrue and DLQOutZukunft ->
Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqout, Now)),
MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied,
werkzeug:logging(Datei, MsgNew ++ "\n");
true ->
werkzeug:logging(Datei, MsgVonGleichemClient ++ "\n")
end.
msgVonGleichemClient(NNr,Msg,NNummern) ->
MsgVonGleichemClient = lists:member(NNr, NNummern),
if
MsgVonGleichemClient -> Msg ++ "*******";
true -> Msg
end.
Config file for server:
{sizedlq,400}.
{servername,'serverpa'}.
{cmemtime,2000}.
{hbqname,'hbqpa'}.
{node,'hbqnode'}.
{serverzeit,50}.
Config file for client:
{wartezeit,20}.
{lebenszeit,240}.
{pratikumsgruppe,'2'}.
{teamnummer,'02'}.
{servername,'serverpa'}.
{clientanzahl,5}.
{servernode,'servernode'}.
{cookie,pa}.
{rechner,'rechner'}.
There are also distributed data strutures which are essentially queues and seem to be working fine:
HBQ:
-module(hbq).
-export([startHBQ/0, checkTransfer/6,loophbq/4]).
%% HBQ !{self(), {request,pushHBQ,[INNr,Msg,TSclientout]}}
startHBQ() ->
startHBQ("./configs/server.cfg").
%% Used for starting the HBQ with a custom config file
startHBQ(Configfile) ->
%%Config und Namen auslesen
Config = loadConfig(Configfile),
Config = loadConfig(Configfile),
%%{ok,Config} = file:consult("./config/server.cfg"),
{ok,HBQName} = werkzeug:get_config_value(hbqname,Config),
%%Prozess der HBQ starten
HBQPid = spawn(?MODULE,loophbq,[[],[],Config, 1]),
%%Prozess registrieren
register(HBQName,HBQPid),
HBQPid.
loophbq(HBQ,DLQ,Config,CurrNumber) ->
receive
%%initialisere HBQ und DLQ, sendet ok an Server
{ServerPid,{request,initHBQ}} ->
HBQList = [],
Log = log(Config,["HBQ>>> initialisiert worden von ", ServerPid, ".\n"]),
{ok,DLQSize} = werkzeug:get_config_file(sizedlq,Config),
DLQ = dlq:initDLQ(DLQSize,Log),
ServerPid ! {reply,ok},
loophbq(HBQList, DLQ ,Config, CurrNumber);
%%fuegt der Msg einen Zeitstempel hinzu, fuegt sie in HBQ ein, sendet ok
{ServerPid,{request,pushHBQ,[NNr,Msg,TSclientout]}} ->
TShbqin = werkzeug:timeMillliSecond(),
NewMessage = {NNr,lists:concat(Msg,["HBQ in: ",TShbqin])},
Log = log(Config,["HBQ>>> Nachricht ",NNr, "in HBQ eingefügt.\n"]),
NewHBQ = [HBQ|NewMessage],
lists:sort(fun({A,_},{B,_}) -> A=<B end),
checkTransfer(NewHBQ, CurrNumber, Config, DLQ,TSclientout,TShbqin),
ServerPid ! {reply,ok},
loophbq(NewHBQ, DLQ ,Config, CurrNumber);
%%DLQ soll über HBQ Nachricht an Client senden
{ServerPid,{request,deliverMSG,NNr,ToClient}} ->
{ok, HBQName} = werkzeug:get_config_value(hbqname, Config),
Log = lists:concat(["HB-DLQ#", HBQName, ".log"]),
Datei = erlang:list_to_atom(Log),
log(Config, ["HBQ>>> dlq:delivermsg", NNr, pid_to_list(ToClient), "\n"]),
NNrDLQ = dlq:deliverMSG(NNr, ToClient, DLQ, Datei),
ServerPid ! {reply, NNrDLQ},
loophbq(HBQ, DLQ ,Config, CurrNumber);
%%Terminiert Prozess der DLQ
{ServerPid,{request,delHBQ}} ->
ServerPid ! {reply,ok},
ok
end.
%%CheckTransfer
checkTransfer(HBQ, Number, Config, [DLQ,Size],TSclientout,TShbqin) ->
Datei = log(Config, ["HBQ>>> Nachricht Nr ", Number, " wird in DLQ uebertragen\n"]),
FoundMatch = lists:keyfind(Number, 1, HBQ),
if FoundMatch =:= false ->
if(length(HBQ)>Size*0.667) ->
[{MinNNr,_}|_] = HBQ,
%wegen sort ist immer die kleinste NNr vorne in der Liste
NewMessage = {MinNNr-1,lists:concat(["Weiß noch nicht was hier reinsoll: ",werkzeug:timeMilliSecond()])},
NewHBQ = lists:append([{MinNNr-1,NewMessage}], HBQ),
log(Config,["HBQ>>> Fehlernachricht fuer Nachrichten ",Number," bis",MinNNr-1, " generiert.\n"]),
NewNumber = MinNNr-1,
checkTransfer(NewHBQ, NewNumber, Config,[DLQ,Size],TSclientout,TShbqin);
true -> ok
end;
true ->
{MatchNr,Msg} = FoundMatch,
dlq:push2DLQ([MatchNr, Msg, TSclientout, TShbqin], DLQ, Datei),
lists:delete(FoundMatch, HBQ),
checkTransfer(HBQ, Number+1, Config,[DLQ,Size],TSclientout,TShbqin)
end.
log(Config,Message) ->
{ok,HBQNode} = werkzeug:get_config_value(node,Config),
DateiName = lists:concat(["HB-DLQ#", HBQNode,".log"]),
Datei = erlang:list_to_atom(DateiName),
werkzeug:logging(Datei, lists:concat(Message)),
Datei.
%%Dummy-Nachrichten schreiben um Lücken in der HBQ zu füllen wenn sie kritische Größe erreicht
%%Methode um zu prüfen, ob Nachrichten in DLQ geschoben werden können, das dann auch machen
loadConfig(Configfile) ->
{ok, Config} = file:consult(Configfile),
Config.
DLQ:
-module(dlq).
-export([initDLQ/2, delDLQ/1, expectedNr/1, push2DLQ/3, deliverMSG/4]).
%%Initialisiert DLQ mit Kapazitaet Size, Log in Datei
initDLQ(Size, Datei) ->
werkzeug:logging(Datei,lists:concat(["DLQ>>> intitialisiert worden mit Groesse ",Size,".\n"])),
[[],Size].
%%Loescht DLQ
delDLQ(_Queue) -> ok.
%%Liefert NNr die als naechstes in DLQ gespeichert werden kann
%%expectedNr(Queue)
expectedNr([[], _Size]) -> 1;
expectedNr([[[NNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] | _Rest], _Size]) -> NNr + 1.
%%Speichert Nachricht in DLQ, fuegt Zeitstempel hinzu, Rueckgabe: Modifizierte DLQ
%%push2DLQ([NNr, Msg, TSclientout, TShbqin], Queue, Datei)
%%Fehlt noch: Abfrage, ob das die passende Nummer ist!
push2DLQ([NNr, Msg, TSclientout, TShbqin], [DLQ,Size], Datei) ->
if
length(DLQ) < Size ->
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])),
[[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | DLQ], Size];
length(DLQ) =:= Size ->
[LastNNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] = lists:last(DLQ),
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", LastNNr, " aus DLQ entfernt.\n"])),
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])),
[[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | lists:droplast(DLQ)], Size]
end.
%%Sendet Nachricht an Leser-Client
deliverMSG(MSGNr, ClientPID, Queue, Datei) ->
%%Aendern: MSGNer = -1, flag am Ende der Reply (siehe zeile 42)
[{NewestNr,Msg}|Rest] = Queue,
if MSGNr > NewestNr ->
DummyMessage = {-1,lists:concat(["DLQ in: ",werkzeug:timeMilliSecond()])}, %% -1 Flag
werkzeug:logging(Datei, lists:concat(["DLQ>>> DummyNachricht fuer ",MSGNr," an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,true}
end,
%%%%%%Ab hier noch aendern bzgl Flag
FoundMatch = lists:keyfind(MSGNr, 1, Queue),
if
FoundMatch =:= false ->
deliverMSG(MSGNr+1, ClientPID, Queue, Datei),
if
MSGNr =:= NewestNr ->
{Number,Msg} = FoundMatch,
NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],-1)},
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,false};
true ->
{Number,Msg} = FoundMatch,
NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],0)},
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,false}
end;
true ->
ok
end.
CMEM:
-module(cmem).
-export([initCMEM/2, delCMEM/1, updateClient/4, getClientNNr/2]).
-import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2,getUTC/0]).
%%Initialisiert CMEM
initCMEM(RemTime, Datei) -> werkzeug:logging(Datei, lists:concat(["CMEM>>> initialisiert mit ", RemTime, " Sekunden\n"])),
[[], RemTime].
%%Loescht CMEM
delCMEM(_CMEM) -> ok.
%%Speichert/aktualisiert Client und NNr im CMEM,
updateClient([CMEM, RemTime], ClientID, NNr, Datei) ->
ClientTS = getUTC(),
logging(Datei, lists:concat(["CMEM>>> Client ", ClientID, " wird aktualisiert.\n"])),
[lists:keystore(ClientID, 1, CMEM, {ClientID, NNr, ClientTS}), RemTime].
%%Gibt naechste vom Client erwartete NNr zurueck
%%Es wird geprueft ob Client in der Liste steht und dann
%%mit diesem Wissen eine Hilfsfunktion aufgerufen
getClientNNr([CMEM, RemTime], ClientID) ->
ClientBekannt = lists:keymember(ClientID, 1, CMEM),
isClientKnown([CMEM, RemTime], ClientID, ClientBekannt).
%%Client ist nicht bekannt: Naechste NNr = 1
isClientKnown(_CMEM, _ClientID, false) -> 1;
%% Der Client ist bekannt.
%%Zeit noch nicht abgelaufen: Gibt naechste Nummer aus
%%Zeit abgelaufen: Naechste NNr = 1
isClientKnown([CMEM, RemTime], ClientID, true) ->
{ClientID, NNr, ClientTS} = lists:keyfind(ClientID, 1, CMEM),
RemainingTime = ClientTS + RemTime,
Now = getUTC(),
if
RemainingTime >= Now -> NNr + 1;
true -> 1
end.
The client is supposed to contact the server sending it a message, the server puts it in data structures which send it back to the client under the right circumstances.
The problem is, when I compile them, the start the HBQ, then the server and then the client, I get
=ERROR REPORT==== 18-Apr-2017::10:25:46 ===
Error in process <0.104.0> with exit value: {distribution_not_started,[{auth,set_cookie,2,[{file,"auth.erl"},{line,119}]},{client,mitServerVerbinden,6,[{file,"client.erl"},{line,42}]}]}
So apparently there is an issue with the client not connecting to the server. This is my first time working with Erlang and distributed systems, so I have no idea what is going on.
Is it not enough to put the nodes and cookie into the configs and tell the components of the system to look there?
The error distribution_not_started is returned by the auth module when the erlang VM calling it does not have a name. Ensure that a -sname or -name flag is passed when starting erlang e.g.:
erl -sname test

esp8266 RTOS blink example doesn't work

I have a problem with the RTOS firmware on the esp8266 (I have a esp12e), after flashing the firmware, reading from uart, it keeps stuck with those lines:
ets Jan 8 2013,rst cause:2, boot mode:(3,0)
load 0x40100000, len 31584, room 16
tail 0
chksum 0x24
load 0x3ffe8000, len 944, room 8
tail 8
chksum 0x9e
load 0x3ffe83b0, len 1080, room 0
tail 8
chksum 0x60
csum 0x60
Now I will explain my HW setup:
GPIO15 -> Gnd
EN -> Vcc
GPIO0 -> Gnd (when flashing)
GPIO0 -> Vcc (normal mode)
For the toolchain I've followed this tutorial and it works well:
http://microcontrollerkits.blogspot.it/2015/12/esp8266-eclipse-development.html
Then I started doing my RTOS blink example, I post my user_main.c code here:
#include "esp_common.h"
#include "gpio.h"
void task2(void *pvParameters)
{
printf("Hello, welcome to client!\r\n");
while(1)
{
// Delay and turn on
vTaskDelay (300/portTICK_RATE_MS);
GPIO_OUTPUT_SET (5, 1);
// Delay and LED off
vTaskDelay (300/portTICK_RATE_MS);
GPIO_OUTPUT_SET (5, 0);
}
}
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
uart_init_new();
printf("SDK version:%s\n", system_get_sdk_version());
// Config pin as GPIO5
PIN_FUNC_SELECT (PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
xTaskCreate(task2, "tsk2", 256, NULL, 2, NULL);
}
I also post the flash command, the first executed one time, the second every time I modify the code:
c:/Espressif/utils/ESP8266/esptool.exe -p COM3 write_flash -ff 40m -fm qio -fs 32m 0x3FC000 c:/Espressif/ESP8266_RTOS_SDK/bin/esp_init_data_default.bin 0x3FE000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin 0x7E000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin
c:/Espressif/utils/ESP8266/esptool.exe -p COM3 -b 256000 write_flash -ff 40m -fm qio -fs 32m 0x00000 firmware/eagle.flash.bin 0x40000 firmware/eagle.irom0text.bin
There is something wrong? I really don't understand why it doesn't work.
When I try the NON-OS example they works very well.
I had the same problem as you. This issue is caused by the incorrect address of the eagle.irom0text.bin .
So I changed the address of the eagle.irom0text.bin from 0x40000 (0x10000) to 0x20000 and it worked well for me.
[RTOS SDK version: 1.4.2(f57d61a)]
The correct flash codes in the common_rtos.mk (ESP-12E)
for flashinit
flashinit:
$(vecho) "Flash init data default and blank data."
$(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fc000 $(SDK_BASE)/bin/esp_init_data_default.bin
$(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fe000 $(SDK_BASE)/bin/blank.bin
for flash:
flash: all
#ifeq ($(app), 0)
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin
else
ifeq ($(boot), none)
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin
else
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) $(addr) $(FW_BASE)/upgrade/$(BIN_NAME).bin
endif
endif

Message exchange between Paho java & javascript client not happening

How can I send a message from paho java client to paho javascript client.
String topic = "chatWith/904";
String content = "Message from MqttPublishSample";
int qos = 0;
String broker = "tcp://127.0.0.1:1883";
String clientId = "JavaSample";
MemoryPersistence persistence = new MemoryPersistence();
try {
MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
System.out.println("Connecting to broker: "+broker);
sampleClient.connect(connOpts);
System.out.println("Connected");
System.out.println("Publishing message: "+content);
MqttMessage message = new MqttMessage(content.getBytes());
message.setQos(qos);
sampleClient.publish(topic, message);
System.out.println("Message published");
sampleClient.disconnect();
System.out.println("Disconnected");
System.exit(0);
} catch(MqttException me) {
me.printStackTrace();
}
Message exchange between two JS client is happening. But between Javasript & java client, message exchange is not happening.
Here is JS code
client = new Messaging.Client(host, Number(port), clientId);
client.onConnect = onConnect;
client.onMessageArrived = onMessageArrived;
client.onMessageDelivered = onMessageDelivered;
client.onConnectionLost = onConnectionLost;
var willMessage = createByteMessage({
id: '',
'msgType':'USER_STATUS',
'status': 'Offline',
'senderId': myUserId,
'senderName': myName
}, statusTopic);
willMessage.retained = true;
client.connect({
userName:user,
password:password,
onSuccess:onConnect,
onFailure:onFailure,
'willMessage': willMessage
});
Here port is 8083 and mqtt broker is emqtt
client.config
testclientid0
testclientid1 127.0.0.1
testclientid2 192.168.0.1/24
emqttd.config
% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% ex: ft=erlang ts=4 sw=4 et
[{kernel, [
{start_timer, true},
{start_pg2, true}
]},
{sasl, [
{sasl_error_logger, {file, "log/emqttd_sasl.log"}}
]},
{ssl, [
%{versions, ['tlsv1.2', 'tlsv1.1']}
]},
{lager, [
{colored, true},
{async_threshold, 5000},
{error_logger_redirect, false},
{crash_log, "log/emqttd_crash.log"},
{handlers, [
%%{lager_console_backend, info},
%%NOTICE: Level >= error
%%{lager_emqtt_backend, error},
{lager_file_backend, [
{formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
{file, "log/emqttd_error.log"},
{level, error},
{size, 104857600},
{date, "$D0"},
{count, 30}
]}
]}
]},
{esockd, [
{logger, {lager, error}}
]},
{emqttd, [
%% Authentication and Authorization
{access, [
%% Authetication. Anonymous Default
{auth, [
%% Authentication with username, password
%{username, []},
%% Authentication with clientid
%{clientid, [{password, no}, {file, "etc/clients.config"}]},
%% Authentication with LDAP
% {ldap, [
% {servers, ["localhost"]},
% {port, 389},
% {timeout, 30},
% {user_dn, "uid=$u,ou=People,dc=example,dc=com"},
% {ssl, fasle},
% {sslopts, [
% {"certfile", "ssl.crt"},
% {"keyfile", "ssl.key"}]}
% ]},
%% Allow all
{anonymous, []}
]},
%% ACL config
{acl, [
%% Internal ACL module
{internal, [{file, "etc/acl.config"}, {nomatch, allow}]}
]}
]},
%% MQTT Protocol Options
{mqtt, [
%% Packet
{packet, [
%% Max ClientId Length Allowed
{max_clientid_len, 512},
%% Max Packet Size Allowed, 64K default
{max_packet_size, 65536}
]},
%% Client
{client, [
%% Socket is connected, but no 'CONNECT' packet received
{idle_timeout, 30} %% seconds
]},
%% Session
{session, [
%% Max number of QoS 1 and 2 messages that can be “in flight” at one time.
%% 0 means no limit
{max_inflight, 100},
%% Retry interval for redelivering QoS1/2 messages.
{unack_retry_interval, 60},
%% Awaiting PUBREL Timeout
{await_rel_timeout, 20},
%% Max Packets that Awaiting PUBREL, 0 means no limit
{max_awaiting_rel, 0},
%% Statistics Collection Interval(seconds)
{collect_interval, 0},
%% Expired after 2 day (unit: minute)
{expired_after, 2880}
]},
%% Queue
{queue, [
%% simple | priority
{type, simple},
%% Topic Priority: 0~255, Default is 0
%% {priority, [{"topic/1", 10}, {"topic/2", 8}]},
%% Max queue length. Enqueued messages when persistent client disconnected,
%% or inflight window is full.
{max_length, infinity},
%% Low-water mark of queued messages
{low_watermark, 0.2},
%% High-water mark of queued messages
{high_watermark, 0.6},
%% Queue Qos0 messages?
{queue_qos0, true}
]}
]},
%% Broker Options
{broker, [
%% System interval of publishing broker $SYS messages
{sys_interval, 60},
%% Retained messages
{retained, [
%% Expired after seconds, never expired if 0
{expired_after, 0},
%% Max number of retained messages
{max_message_num, 100000},
%% Max Payload Size of retained message
{max_playload_size, 65536}
]},
%% PubSub and Router
{pubsub, [
%% Default should be scheduler numbers
{pool_size, 8},
%% Store Subscription: true | false
{subscription, true},
%% Route aging time(seconds)
{route_aging, 5}
]},
%% Bridge
{bridge, [
%%TODO: bridge queue size
{max_queue_len, 10000},
%% Ping Interval of bridge node
{ping_down_interval, 1} %seconds
]}
]},
%% Modules
{modules, [
%% Client presence management module.
%% Publish messages when client connected or disconnected
{presence, [{qos, 0}]},
%% Subscribe topics automatically when client connected
{subscription, [
%% $c will be replaced by clientid
%% {"$queue/clients/$c", 1},
%% Static subscriptions from backend
backend
]}
%% Rewrite rules
%% {rewrite, [{file, "etc/rewrite.config"}]}
]},
%% Plugins
{plugins, [
%% Plugin App Library Dir
{plugins_dir, "./plugins"},
%% File to store loaded plugin names.
{loaded_file, "./data/loaded_plugins"}
]},
%% Listeners
{listeners, [
{mqtt, 1883, [
%% Size of acceptor pool
{acceptors, 16},
%% Maximum number of concurrent clients
{max_clients, 512},
%% Socket Access Control
{access, [{allow, all}]},
%% Connection Options
{connopts, [
%% Rate Limit. Format is 'burst, rate', Unit is KB/Sec
%% {rate_limit, "100,10"} %% 100K burst, 10K rate
]},
%% Socket Options
{sockopts, [
%Set buffer if hight thoughtput
%{recbuf, 4096},
%{sndbuf, 4096},
%{buffer, 4096},
%{nodelay, true},
{backlog, 1024}
]}
]},
{mqtts, 8883, [
%% Size of acceptor pool
{acceptors, 4},
%% Maximum number of concurrent clients
{max_clients, 512},
%% Socket Access Control
{access, [{allow, all}]},
%% SSL certificate and key files
{ssl, [{certfile, "etc/ssl/ssl.crt"},
{keyfile, "etc/ssl/ssl.key"}]},
%% Socket Options
{sockopts, [
{backlog, 1024}
%{buffer, 4096},
]}
]},
%% WebSocket over HTTPS Listener
%% {https, 8083, [
%% %% Size of acceptor pool
%% {acceptors, 4},
%% %% Maximum number of concurrent clients
%% {max_clients, 512},
%% %% Socket Access Control
%% {access, [{allow, all}]},
%% %% SSL certificate and key files
%% {ssl, [{certfile, "etc/ssl/ssl.crt"},
%% {keyfile, "etc/ssl/ssl.key"}]},
%% %% Socket Options
%% {sockopts, [
%% %{buffer, 4096},
%% {backlog, 1024}
%% ]}
%%]},
%% HTTP and WebSocket Listener
{http, 8083, [
%% Size of acceptor pool
{acceptors, 4},
%% Maximum number of concurrent clients
{max_clients, 64},
%% Socket Access Control
{access, [{allow, all}]},
%% Socket Options
{sockopts, [
{backlog, 1024}
%{buffer, 4096},
]}
]}
]},
%% Erlang System Monitor
{sysmon, [
%% Long GC, don't monitor in production mode for:
%% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421
{long_gc, false},
%% Long Schedule(ms)
{long_schedule, 240},
%% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
%% 8 * 1024 * 1024
{large_heap, 8388608},
%% Busy Port
{busy_port, false},
%% Busy Dist Port
{busy_dist_port, true}
]}
]}
].

OpenCV error when running make CentOS

I am trying to install OpenCV 2.4.2 on CentOS 5.8 but I get the following error
[ 34%] Built target opencv_test_highgui
[ 34%] Building CXX object modules/features2d/CMakeFiles/opencv_features2d.dir/src/freak.cpp.o
/home/jtrinidad/Downloads/OpenCV-2.4.2/modules/core/include/opencv2/core/core.hpp:1286: warning: ‘class cv::_InputArray’ has virtual functions but non-virtual destructor
/home/jtrinidad/Downloads/OpenCV-2.4.2/modules/core/include/opencv2/core/core.hpp:1365: warning: ‘class cv::_OutputArray’ has virtual functions but non-virtual destructor
/home/jtrinidad/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp: In member function ‘virtual void cv::FREAK::computeImpl(const cv::Mat&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::Mat&) const’:
/home/jtrinidad/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp:367: error: shift must be an immediate
make[2]: *** [modules/features2d/CMakeFiles/opencv_features2d.dir/src/freak.cpp.o] Error 1
make[1]: *** [modules/features2d/CMakeFiles/opencv_features2d.dir/all] Error 2
make: *** [all] Error 2
I ran the following command on cmake
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_EXAMPLES=OFF WITH_CUDA=OFF ..
Thank you.
The problem was resolved.
I applied the following patch to ~/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp
diff -crB OpenCV-2.4.2.orig/modules/features2d/src/freak.cpp OpenCV-2.4.2/modules/features2d/src/freak.cpp
*** OpenCV-2.4.2.orig/modules/features2d/src/freak.cpp 2012-07-25 09:54:50.000000000 -0400
--- OpenCV-2.4.2/modules/features2d/src/freak.cpp 2012-07-24 10:34:57.000000000 -0400
***************
*** 364,370 ****
__m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
workReg = _mm_cmpeq_epi8(workReg, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
! workReg = _mm_and_si128(_mm_srli_epi16(binMask, m), workReg); // merge the last 16 bits with the 128bits std::vector until full
result128 = _mm_or_si128(result128, workReg);
}
(*ptr) = result128;
--- 364,404 ----
__m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
workReg = _mm_cmpeq_epi8(workReg, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
! // merge the last 16 bits with the 128bits std::vector until full
! __m128i shiftedMask;
! switch(m) {
! case 8:
! shiftedMask = _mm_srli_epi16(binMask, 8);
! break;
! case 7:
! shiftedMask = _mm_srli_epi16(binMask, 7);
! break;
! case 6:
! shiftedMask = _mm_srli_epi16(binMask, 6);
! break;
! case 5:
! shiftedMask = _mm_srli_epi16(binMask, 5);
! break;
! case 4:
! shiftedMask = _mm_srli_epi16(binMask, 4);
! break;
! case 3:
! shiftedMask = _mm_srli_epi16(binMask, 3);
! break;
! case 2:
! shiftedMask = _mm_srli_epi16(binMask, 2);
! break;
! case 1:
! shiftedMask = _mm_srli_epi16(binMask, 1);
! break;
! case 0:
! shiftedMask = _mm_srli_epi16(binMask, 0);
! break;
! default:
! throw "shifting less than 0";
! }
! workReg = _mm_and_si128(shiftedMask, workReg);
!
result128 = _mm_or_si128(result128, workReg);
}
(*ptr) = result128;
This full patch file: http://code.opencv.org/projects/opencv/repository/revisions/65f85856306575e4d71164c8212e84d26424cf0f
After trying to use patches, I resorted to compile freak.cpp manually. My notes on the installation are available here: http://www.megalinux.net/compiling-opencv-2-4-on-rhelcentos-5/

Resources