@@ -533,8 +533,9 @@ function BodePlot(handles, undock, exportData)
533533 for i = 1 : length(handles .SelectedListboxContents )
534534 LoopGain(1 ,i ) = series(ControllerLG(: ,i ), Plant(: ,i ));
535535 end
536-
537- w = logspace(-2 ,2 ,1000 );
536+
537+ w_limit = 2 ; % change this limit if one of the margins can't be found
538+ w = logspace(-w_limit , w_limit ,1000 );
538539 Controller_FRF = freqresp(Controller , w );
539540 ControllerLG_FRF = freqresp(ControllerLG , w );
540541 Controller_MagResponse = mag2db(squeeze(abs(Controller_FRF )))' ;
@@ -553,51 +554,55 @@ function BodePlot(handles, undock, exportData)
553554 if size(Controller_MagResponse , 1 ) == 1
554555 Controller_MagResponse = Controller_MagResponse(: );
555556 Controller_PhaseResponse = Controller_PhaseResponse(: );
557+ LoopGainMagResponseAbs = LoopGainMagResponseAbs(: );
556558 LoopGainMagResponse = LoopGainMagResponse(: );
557559 LoopGainPhaseResponse = LoopGainPhaseResponse(: );
558560 PlantMagResponse = PlantMagResponse(: );
559561 PlantPhaseResponse = PlantPhaseResponse(: );
560562 end
563+
564+ % Stability margins calculation
565+ cell_prealloc = cell(1 ,length(handles .SelectedListboxContents ));
566+ S = struct(' GainMargin' , cell_prealloc , ...
567+ ' GMFrequency' , cell_prealloc , ...
568+ ' PhaseMargin' , cell_prealloc , ...
569+ ' PMFrequency' , cell_prealloc , ...
570+ ' DelayMargin' , cell_prealloc , ...
571+ ' DMFrequency' , cell_prealloc , ...
572+ ' Stable' , cell_prealloc );
573+ GM = zeros(1 , length(handles .SelectedListboxContents ));
574+ PM = GM ;
575+ GMFreq = GM ;
576+ PMFreq = GM ;
577+ for i = 1 : length(handles .SelectedListboxContents )
578+ S(i ) = allmargin(LoopGainMagResponseAbs(: ,i ),LoopGainPhaseResponse(: ,i ),w ' );
579+ GM(i ) = mag2db(S(i ).GainMargin(1 ));
580+ PM(i ) = S(i ).PhaseMargin(1 );
581+ GMFreq(i ) = S(i ).GMFrequency(1 );
582+ PMFreq(i ) = S(i ).PMFrequency(1 );
583+ end
584+
585+ if get(handles .PlotGMPM_checkbox ,' value' )
586+ legendMargins = cell(length(handles .SelectedListboxContents ), 6 );
587+ legendMargins(: ,1 ) = {' GM: ' };
588+ legendMargins(: ,3 ) = {' [dB] ' };
589+ legendMargins(: ,4 ) = {' PM: ' };
590+ legendMargins(: ,6 ) = {' [deg] ' };
561591
562- if get(handles .PlotLoopGain_checkbox ,' value' )
563- if get(handles .PlotGMPM_checkbox ,' value' )
564- legendMargins = cell(length(handles .SelectedListboxContents ), 6 );
565- legendMargins(: ,1 ) = {' GM: ' };
566- legendMargins(: ,3 ) = {' [dB] ' };
567- legendMargins(: ,4 ) = {' PM: ' };
568- legendMargins(: ,6 ) = {' [deg] ' };
569- end
570592 if length(handles .SelectedListboxContents ) == 1
571- S = allmargin(LoopGainMagResponseAbs ,LoopGainPhaseResponse ,w ' );
572- GM = S .GainMargin(1 );
573- PM = S .PhaseMargin(1 );
574- GMFreq = S .GMFrequency(1 );
575- PMFreq = S .PMFrequency(1 );
576-
577- if get(handles .PlotGMPM_checkbox ,' value' )
578- legendMargins{2 } = num2str(mag2db(GM ));
579- legendMargins{5 } = num2str(PM );
580- legendMargins = strcat(legendMargins{1 }, legendMargins{2 }, ...
581- legendMargins{3 }, legendMargins{4 }, legendMargins{5 }, ...
582- legendMargins{6 });
583- end
593+ legendMargins{2 } = num2str(GM );
594+ legendMargins{5 } = num2str(PM );
595+ legendMargins = strcat(legendMargins{1 }, legendMargins{2 }, ...
596+ legendMargins{3 }, legendMargins{4 }, legendMargins{5 }, ...
597+ legendMargins{6 });
584598 else
585599 for i = 1 : length(handles .SelectedListboxContents )
586- S(i ) = allmargin(LoopGainMagResponseAbs(: ,i ),LoopGainPhaseResponse(: ,i ),w ' );
587- GM(i ) = S(i ).GainMargin(1 );
588- PM(i ) = S(i ).PhaseMargin(1 );
589- GMFreq(i ) = S(i ).GMFrequency(1 );
590- PMFreq(i ) = S(i ).PMFrequency(1 );
591- if get(handles .PlotGMPM_checkbox ,' value' )
592- legendMargins{i ,2 } = num2str(mag2db(GM(i )));
593- legendMargins{i ,5 } = num2str(PM(i ));
594- end
595- end
596- if get(handles .PlotGMPM_checkbox ,' value' )
597- legendMargins = strcat(legendMargins(: ,1 ), legendMargins(: ,2 ), ...
598- legendMargins(: ,3 ), legendMargins(: ,4 ), legendMargins(: ,5 ), ...
599- legendMargins(: ,6 ));
600+ legendMargins{i ,2 } = num2str(GM(i ));
601+ legendMargins{i ,5 } = num2str(PM(i ));
600602 end
603+ legendMargins = strcat(legendMargins(: ,1 ), legendMargins(: ,2 ), ...
604+ legendMargins(: ,3 ), legendMargins(: ,4 ), legendMargins(: ,5 ), ...
605+ legendMargins(: ,6 ));
601606 end
602607 end
603608
@@ -630,8 +635,8 @@ function BodePlot(handles, undock, exportData)
630635 end
631636 if get(handles .PlotLoopGain_checkbox , ' Value' )
632637 if get(handles .PlotGMPM_checkbox ,' value' )
633- h(i ) = semilogx([GMFreq(i ) GMFreq(i )], [0 - mag2db( GM(i ) )], ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{2 }, ' LineWidth' , plotLineWidth(1 ));
634- h(i ) = semilogx(GMFreq(i ), - mag2db( GM(i ) ), ' o' , ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{1 }, ' LineWidth' , plotLineWidth(1 ));
638+ h(i ) = semilogx([GMFreq(i ) GMFreq(i )], [0 - GM(i )], ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{2 }, ' LineWidth' , plotLineWidth(1 ));
639+ h(i ) = semilogx(GMFreq(i ), - GM(i ), ' o' , ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{1 }, ' LineWidth' , plotLineWidth(1 ));
635640
636641 end
637642 h(i ) = semilogx(w , LoopGainMagResponse(: ,i ), ' Color' , ones(1 ,3 )*plotCol(i ), ' LineStyle' , plotLineStyle{3 }, ' LineWidth' , plotLineWidth(3 ));
@@ -669,25 +674,25 @@ function BodePlot(handles, undock, exportData)
669674 if get(handles .PlotLoopGain_checkbox , ' Value' )
670675 semilogx(w , LoopGainPhaseResponse(: ,i ), ' Color' , ones(1 ,3 )*plotCol(i ), ' LineStyle' , plotLineStyle{3 }, ' LineWidth' , plotLineWidth(3 ));
671676 hold on
672- if PM(i ) >= 0
673- dotPM = - 180 + PM(i );
674- else
675- dotPM = 180 + PM(i );
676- end
677- linePM = [-180 dotPM ];
678677 if get(handles .PlotGMPM_checkbox ,' value' )
678+ if PM(i ) >= 0
679+ dotPM = - 180 + PM(i );
680+ else
681+ dotPM = 180 + PM(i );
682+ end
683+ linePM = [-180 dotPM ];
679684 h(i ) = semilogx([PMFreq(i ) PMFreq(i )], linePM , ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{2 }, ' LineWidth' , plotLineWidth(1 ));
680685 h(i ) = semilogx(PMFreq(i ), dotPM , ' o' , ' Color' , [0 0.8 0 ], ' LineStyle' , plotLineStyle{1 }, ' LineWidth' , plotLineWidth(1 ));
681686 end
682687 end
683688 end
684- semilogx(w , 180 * ones(1 ,length(w )), w , - 180 * ones(1 ,length(w )), ' LineStyle' , ' --' , ' Color' , ' k' , ' LineWidth' , 0.5 )
689+ semilogx(w , 180 * ones(1 ,length(w )), w , - 180 * ones(1 ,length(w )), ' LineStyle' , ' --' , ' Color' , ' k' , ' LineWidth' , 0.5 );
685690 xlabel(' Frequency [rad/s]' )
686691 ylabel(' Phase [deg]' )
687692 set(gca , ' XScale' , ' log' )
688693 grid on
689694
690- if undock % TODO: make available also for the docked figures
695+ if undock
691696 figureHandle = findobj(Plot ,' Type' ,' axes' ,' Visible' ,' on' );
692697 try
693698 linkaxes(figureHandle ,' x' )
0 commit comments