2017-05-02 2 views
1

Je tracer des données en temps réel dans Matlab (reçu via un port série), et je l'ai trouvé une curieuse façon d'influer sur le taux de rafraîchissement: changer la taille de la terrain. Quand l'intrigue est "normale", elle aura ~ 35fps, et comme je la rétrécis, elle dépassera 120fps. Cependant, lorsque j'utilise exactement la même configuration de tracé, mais que je trace simplement les données générées aléatoirement pour chaque boucle, le taux de rafraîchissement n'est pas affecté par la taille du tracé. Malheureusement, visionneuse de profil (2017A) ne peut pas voir à l'intérieur du tracé, et les attributs que tout le temps d'attente au port série - ce qui est impossible, étant donné le taux de rafraîchissement variables décrit ci-dessus (aussi, je l'ai testé un nu -bones appel et réponse en série, et l'aller-retour pour Matlab est sous 8ms (~ 120fps)). Les exemples de deux boucles ne sont pas destinés à obtenir le même taux de framerate, ils sont simplement pour démontrer que lorsque l'on change la taille de la parcelle (saisir manuellement un coin et l'ajuster, ou utiliser le paramètre position) serial) est énormément affectée par la taille, et le second exemple (random) ne l'est pas.en temps réel Matlab parcelle taux de rafraîchissement est affectée par la taille des parcelles

Addition:

Après avoir joué avec une version modifiée de celui-ci où l'intrigue est mis à jour par un rappel de la minuterie, je vois que je peux soit faire la boucle de lecture série rapide (~ 170Hz) ou mettre à jour l'intrigue rapide (~ 170Hz). Cependant, l'autre souffre toujours. Et si je change itérativement la période de temporisation pour obtenir le même taux de mise à jour pour les deux, sans surprise, c'est presque exactement le même taux que je reçois avec la boucle montrée ci-dessous. Il serait bien de mettre la mise à jour de la mise à jour sur un fil séparé, sans passer par les étapes de l'appel d'un processus Matlab séparé et de la communication entre les deux.

configuration du terrain:

figure_h = figure(); 
set(figure_h, 'KeyPressFcn', @key_press_function); 
set(figure_h, 'WindowButtonDownFcn', {@click_callback, obj}) 

%some random things that drastically speed up the plotting 
set(figure_h, 'Position', [100, 100, 350, 350]); %the size has a huge effect on performance 
set(figure_h, 'MenuBar', 'none'); 
set(figure_h, 'GraphicsSmoothing', 'Off'); 
set(figure_h, 'DockControls', 'Off'); 
set(figure_h, 'NumberTitle', 'Off'); 
set(figure_h, 'ToolBar', 'none'); 

%create plots 
scatter_h = plot(number_array(:,1)*scale, number_array(:,2)*scale, 'r.'); 
set(scatter_h, 'MarkerSize',8); 
set(scatter_h, 'Clipping','off'); 
hold on 
axis square 
grid on 
ylim([min_value, max_value*scale]); 
xlim([min_value, max_value*scale]); 
set(figure_h.CurrentAxes, 'xtick', [min_value:max_value/10:max_value]); %#ok<NBRAK> 
set(figure_h.CurrentAxes, 'ytick', [min_value:max_value/10:max_value]); %#ok<NBRAK> 
set(figure_h.CurrentAxes, 'XTickLabel',[]); 
set(figure_h.CurrentAxes, 'YTickLabel',[]); 
set(figure_h.CurrentAxes, 'ZTickLabel',[]); 
set(figure_h.CurrentAxes, 'ZGrid', 'off'); 
set(figure_h.CurrentAxes, 'XLimMode', 'manual'); 
set(figure_h.CurrentAxes, 'YLimMode', 'manual'); 
set(figure_h.CurrentAxes, 'ZLimMode', 'manual'); 
set(figure_h.CurrentAxes, 'ALimMode', 'manual'); 
set(figure_h.CurrentAxes, 'CLimMode', 'manual'); 
set(figure_h.CurrentAxes, 'DataAspectRatioMode', 'manual'); 
set(figure_h.CurrentAxes, 'CameraPositionMode', 'manual'); 
set(figure_h.CurrentAxes, 'CameraPosition', [max_value/2,max_value/2,1]); 
set(figure_h.CurrentAxes, 'CameraTargetMode', 'manual'); 
set(figure_h.CurrentAxes, 'CameraTarget', [max_value/2,max_value/2,0]); 
set(figure_h.CurrentAxes, 'CameraUpVectorMode', 'manual'); 
set(figure_h.CurrentAxes, 'CameraUpVector', [0,1,0]); 
set(figure_h.CurrentAxes, 'CameraViewAngleMode', 'manual'); 
set(figure_h.CurrentAxes, 'CameraViewAngle', 180); 
set(figure_h.CurrentAxes, 'GridAlphaMode', 'manual'); 
set(figure_h.CurrentAxes, 'Clipping', 'off'); 
circle_h = line((radius*cos(theta) + center_x)*scale,(radius*sin(theta) + center_y)*scale); 
hold off 

boucle simplifiée pour série:

while keep_running 

    %must wait for next packet to arrive 
    bytes = obj.bytes_available; 
    while keep_running && (bytes == 0) 
     bytes = obj.bytes_available; //function call actually directly uses the java serial objects for speed   
    end 

    %send request for next packet 
    obj.send_command(obj.cmd_id.cmd_history, true); //sends synchronously, otherwise, with async, an additional wait loop is necessary to prevent an async call if serial is still transmitting (Matlab throws an error otherwise - why they can't be queued, I don't know) 

    %grab the available buffer 
    new_buffer = obj.buffer_available(bytes); 

    %append new characters to running buffer 
    char_buffer = strcat(char_buffer, new_buffer); 

    %process buffer for all arrays 
    while (~isempty(strfind(char_buffer, '[')) && ~isempty(strfind(char_buffer, ']'))) %#ok<STREMP> 

     %extract a number array 
     [number_array, char_buffer] = extract_hex_array(char_buffer,3,2); 

     if ~isempty(number_array) 
      %remove any duplicate points 
      number_array = unique(number_array, 'rows', 'stable'); 

      frames = frames + 1; 

      %update data 
      set(scatter_h, 'xdata', number_array(:,1)*scale, 'ydata', number_array(:,2)*scale); 

      %update header information (after stabilization, and every 10 frames) 
      if frames > 25 && mod(frames, 10) == 0 
       avg_framerate = frames/toc(total_time); 
       set(figure_h, 'Name', strcat('rate: ', num2str(avg_framerate, '%.1f'), ' Hz buffer: ',num2str(length(char_buffer), '%05d'))); 
      end 

      %just a small delay, but not too small the callbacks stop working 
      pause(0.005); 
     end 
    end 
end 

factice boucle de données aléatoires:

start_tic = tic; 
for i=1:200 
    array1 = 4095*rand(82,2); 
    set(scatter_h, 'xdata', array1(:,1), 'ydata', array1(:,2)); 
    pause(0.005); 
end 
end_tic = toc(start_tic); 
fprintf("fps: %f\n", i/end_tic); 
+0

Juste une note sur la définition des propriétés. vous pouvez définir plusieurs propriétés dans la fonction 'set', en particulier lorsque leurs valeurs sont les mêmes: ' set (figure_h.CurrentAxes, {'XLimMode', 'YLimMode', 'ZLimMode', ... ' ' 'ALimMode ',' CLimMode ',' DataAspectRatioMode ',' CameraPositionMode ', ... '' CameraTargetMode', 'CameraUpVectorMode', 'CameraViewAngleMode', ... '' ''GridAlphaMode'}, repmat ({'manual'} , 1,11)); – Anthony

Répondre

0

Après avoir soumis une demande de service avec Mathworks, la réponse officielle est que Matlab 2017a et avant n'utilisent pas OpenGL sur Mac (même si la commande "opengl info" sa ys il est supporté). Par conséquent, le tracé ne sera pas aussi rapide sur MacOS que sur Windows tant qu'ils n'auront pas corrigé leurs bibliothèques de traçage.