<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>controle H-infinito - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/controle-h-infinito/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Mon, 24 Mar 2025 01:58:39 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>controle H-infinito - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Algoritmos de Controle de Loop Fechado: Guia Completo com PID e Exemplos em C</title>
		<link>https://mcu.tec.br/algoritimos/algoritmos-de-controle-de-loop-fechado-guia-completo-com-pid-e-exemplos-em-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=algoritmos-de-controle-de-loop-fechado-guia-completo-com-pid-e-exemplos-em-c</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 21 Mar 2025 15:10:44 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[algoritmo PID em C]]></category>
		<category><![CDATA[controlador PID]]></category>
		<category><![CDATA[controle adaptativo]]></category>
		<category><![CDATA[controle automático]]></category>
		<category><![CDATA[controle Bang-Bang]]></category>
		<category><![CDATA[controle de loop fechado]]></category>
		<category><![CDATA[controle de motor]]></category>
		<category><![CDATA[controle de posição]]></category>
		<category><![CDATA[controle de temperatura]]></category>
		<category><![CDATA[controle de velocidade]]></category>
		<category><![CDATA[controle embarcado]]></category>
		<category><![CDATA[controle H-infinito]]></category>
		<category><![CDATA[controle LQR]]></category>
		<category><![CDATA[controle PD]]></category>
		<category><![CDATA[controle PI]]></category>
		<category><![CDATA[engenharia de controle]]></category>
		<category><![CDATA[exemplo de PID em C]]></category>
		<category><![CDATA[microcontrolador]]></category>
		<category><![CDATA[sistemas de controle digital]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=202</guid>

					<description><![CDATA[<p>Aprenda tudo sobre algoritmos de controle de loop fechado, incluindo PID, PI, PD, Bang-Bang, LQR e H∞. Veja explicações detalhadas, fórmulas matemáticas e exemplos práticos em linguagem C para microcontroladores.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/algoritmos-de-controle-de-loop-fechado-guia-completo-com-pid-e-exemplos-em-c/">Algoritmos de Controle de Loop Fechado: Guia Completo com PID e Exemplos em C</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Os algoritmos de controle de loop fechado são fundamentais na engenharia de sistemas embarcados, automação industrial e em diversas aplicações onde a estabilidade e o desempenho do sistema precisam ser mantidos diante de variações internas ou externas. Diferentemente dos sistemas de controle de malha aberta, que agem de forma predefinida sem considerar a resposta real do sistema, os sistemas de malha fechada utilizam informações em tempo real de sensores para ajustar continuamente o comportamento do atuador. Este artigo explora os principais tipos de algoritmos de controle de loop fechado, com ênfase nos controladores PID (Proporcional-Integral-Derivativo) e suas variantes. Também serão discutidos controladores como PD, PI, Bang-Bang, controle por modelo (MPC) e controle adaptativo. Para cada tipo, serão apresentadas suas características, equações matemáticas, vantagens, desvantagens, estratégias de implementação e exemplos práticos em linguagem C.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. Problema a Ser Resolvido</h2>



<p class="wp-block-paragraph">Em sistemas de controle, o objetivo fundamental é garantir que uma determinada variável de interesse (como temperatura, velocidade, posição ou corrente) siga um valor desejado, chamado de referência ou setpoint, mesmo na presença de perturbações e incertezas do ambiente. Em aplicações embarcadas, industriais ou robóticas, por exemplo, controlar com precisão e estabilidade a velocidade de um motor, a posição de um atuador linear ou a pressão em um sistema hidráulico é uma exigência recorrente.</p>



<p class="wp-block-paragraph">O desafio é que muitos sistemas físicos apresentam comportamentos dinâmicos complexos, como atraso de resposta, não linearidades, ruídos de medição ou variações imprevisíveis em sua carga. Além disso, o próprio modelo matemático que descreve o sistema nem sempre é conhecido com exatidão. Esses fatores dificultam a obtenção de um controle confiável apenas por meio de métodos de malha aberta, que operam sem considerar o resultado real das ações de controle. Tais métodos não são capazes de compensar desvios causados por interferências externas ou mudanças na planta controlada.</p>



<p class="wp-block-paragraph">Diante disso, os algoritmos de controle de loop fechado surgem como solução indispensável. Eles utilizam um sensor para medir a saída do sistema, comparam essa medida com o valor de referência e geram automaticamente um sinal de erro. Com base nesse erro, o algoritmo calcula uma nova ação de controle, ajustando dinamicamente o sistema em tempo real. Esse mecanismo de retroalimentação (ou realimentação) é o coração dos sistemas de malha fechada, permitindo que o sistema reaja a distúrbios, compense desvios e mantenha a estabilidade desejada.</p>



<p class="wp-block-paragraph">O problema, portanto, consiste em projetar algoritmos capazes de realizar essa regulação automática de forma eficiente, estável e robusta, mesmo em contextos com recursos computacionais limitados, como nos microcontroladores embarcados. O tipo de controlador ideal dependerá das características do sistema controlado, dos requisitos de desempenho e das limitações práticas do hardware.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="700" height="291" src="https://mcu.tec.br/wp-content/uploads/2025/03/image-12.png" alt="" class="wp-image-230" srcset="https://mcu.tec.br/wp-content/uploads/2025/03/image-12.png 700w, https://mcu.tec.br/wp-content/uploads/2025/03/image-12-300x125.png 300w" sizes="(max-width: 700px) 100vw, 700px" /></figure>
</div>


<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. Estrutura Geral dos Algoritmos de Controle de Loop Fechado</h2>



<p class="wp-block-paragraph">A estrutura típica de um sistema de controle de loop fechado baseia-se na interação entre três elementos principais: o sensor, o controlador e o atuador, todos conectados em um ciclo contínuo de realimentação. Esse arranjo pode ser descrito pela seguinte sequência funcional:</p>



<ol class="wp-block-list">
<li><strong>Leitura da variável de processo (PV – Process Variable):</strong> um sensor coleta, em tempo real, o valor atual da variável a ser controlada, como a temperatura de um forno ou a velocidade de um motor.</li>



<li><strong>Cálculo do erro:</strong> o controlador recebe o valor atual e o compara com o valor desejado (setpoint ou referência), calculando a diferença entre ambos: \(e(t) = r(t) &#8211; y(t)\) onde:
<ul class="wp-block-list">
<li>e(t) é o erro no instante t,</li>



<li>r(t) é o valor de referência (setpoint),</li>



<li>y(t) é a saída medida do sistema.</li>
</ul>
</li>



<li><strong>Ação de controle:</strong> com base nesse erro, o algoritmo determina o sinal de controle \(u(t)\) a ser aplicado no atuador. A forma como esse cálculo é feito depende do tipo de controlador (PID, Bang-Bang, adaptativo, etc.).</li>



<li><strong>Atualização do sistema:</strong> o atuador aplica o sinal de controle no processo, modificando a variável de interesse. O ciclo se repete periodicamente.</li>
</ol>



<p class="wp-block-paragraph">Essa estrutura é resumida no chamado <strong>diagrama de blocos de controle</strong>, com um laço de realimentação (feedback) que retroalimenta o sistema com a resposta obtida para recalcular o erro continuamente. Em sistemas digitais (como microcontroladores), esse ciclo é discretizado em passos regulares de tempo \(T_s\) (período de amostragem), onde o controle é reavaliado a cada iteração.</p>



<p class="wp-block-paragraph">A implementação computacional desse ciclo envolve uma rotina que é executada em loop infinito ou em um temporizador periódico (timer), garantindo que o sistema responda em tempo real às alterações da planta.</p>



<p class="wp-block-paragraph">A seguir, um esboço simplificado em C para ilustrar a estrutura de controle de malha fechada:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define SAMPLE_TIME_MS 10  // tempo de amostragem em milissegundos

float setpoint = 100.0;    // valor desejado
float process_variable = 0.0;  // valor medido do sensor
float error = 0.0;         // erro entre setpoint e medição
float control_signal = 0.0;  // valor de saída para o atuador

void control_loop(void) {
    process_variable = read_sensor();          // Leitura da PV
    error = setpoint - process_variable;       // Cálculo do erro
    control_signal = compute_control(error);   // Função de controle (PID, etc.)
    write_actuator(control_signal);            // Aplicação no sistema
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#define SAMPLE_TIME_MS 10  // tempo de amostragem em milissegundos</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100.0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">desejado</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">process_variable</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">medido</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sensor</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">         </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">erro</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">entre</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">medição</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control_signal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">saída</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">atuador</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control_loop</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">void</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">process_variable</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">read_sensor</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">          </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Leitura</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PV</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">process_variable</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">       </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Cálculo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">erro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">control_signal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">error</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Função</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controle</span><span style="color: #D8DEE9FF"> (PID, </span><span style="color: #A3BE8C">etc.</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">write_actuator(control_signal</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Aplicação</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">no</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sistema</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa função <code>control_loop()</code> seria chamada periodicamente por um timer, por exemplo a cada 10 ms, mantendo o sistema sob controle constante.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. Tipos de Algoritmos de Controle de Loop Fechado</h2>



<p class="wp-block-paragraph">Os algoritmos de controle de loop fechado podem assumir diferentes formas, dependendo da natureza da planta, dos requisitos de desempenho e da capacidade de processamento disponível. A seguir, exploramos os tipos mais comuns, destacando suas características fundamentais, equações matemáticas e formas de implementação.</p>



<h3 class="wp-block-heading">4.1 Controlador Proporcional (P)</h3>



<p class="wp-block-paragraph">O controlador proporcional é o mais simples entre os algoritmos clássicos. Ele ajusta o sinal de controle de forma proporcional ao erro presente:</p>



<p class="wp-block-paragraph">\[<br>u(t) = K_p \cdot e(t)<br>\]



<ul class="wp-block-list">
<li>u(t): sinal de controle;</li>



<li>\(K_p\): ganho proporcional;</li>



<li>e(t): erro entre o setpoint e a variável de processo.</li>
</ul>



<p class="wp-block-paragraph">Esse controlador atua de forma rápida, mas nunca zera completamente o erro em sistemas com dinâmica estável. Ele é frequentemente usado quando alguma margem de erro é aceitável ou em combinação com outros termos.</p>



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float Kp = 2.0;

float compute_control(float error) {
    return Kp * error;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.2 Controlador Proporcional-Integral (PI)</h3>



<p class="wp-block-paragraph">O PI é uma evolução do P e busca eliminar o erro em regime permanente. O termo integral acumula o erro ao longo do tempo: \(u(t) = K_p \cdot e(t) + K_i \cdot \int_0^t e(\tau)\,d\tau\)</p>



<p class="wp-block-paragraph">Em tempo discreto (digital), o termo integral pode ser aproximado por uma soma acumulativa: </p>



<p class="wp-block-paragraph">\[<br>u[k] = K_p \cdot e[k] + K_i \cdot T_s \cdot \sum_{i=0}^k e[i]<br>\]



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float Kp = 1.5;
float Ki = 0.8;
float integral = 0.0;
float Ts = 0.01;  // 10 ms

float compute_control(float error) {
    integral += error * Ts;
    return Kp * error + Ki * integral;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.5</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.8</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ms</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">integral</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.3 Controlador Proporcional-Derivativo (PD)</h3>



<p class="wp-block-paragraph">O controlador PD adiciona um termo que considera a taxa de variação do erro. Isso melhora a resposta dinâmica e reduz o sobretempo: </p>



<p class="wp-block-paragraph">\[<br>u(t) = K_p \cdot e(t) + K_d \cdot \frac{de(t)}{dt}<br>\]



<p class="wp-block-paragraph">Na forma discreta: </p>



<p class="wp-block-paragraph">\[<br>u[k] = K_p \cdot e[k] + K_d \cdot \frac{e[k] &#8211; e[k-1]}{T_s}<br>\]



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float Kp = 2.0;
float Kd = 0.5;
float Ts = 0.01;
float previous_error = 0.0;

float compute_control(float error) {
    float derivative = (error - previous_error) / Ts;
    previous_error = error;
    return Kp * error + Kd * derivative;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.5</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">previous_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (error </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">previous_error</span><span style="color: #D8DEE9FF">) / Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">previous_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.4 Controlador Proporcional-Integral-Derivativo (PID)</h3>



<p class="wp-block-paragraph">O PID é o controlador mais utilizado em sistemas industriais. Ele combina os efeitos do controle proporcional, integral e derivativo: </p>



<p class="wp-block-paragraph">\[<br>u(t) = K_p \cdot e(t) + K_i \cdot \int_0^t e(\tau)\,d\tau + K_d \cdot \frac{de(t)}{dt}<br>\]



<p class="wp-block-paragraph">Em tempo discreto: </p>



<p class="wp-block-paragraph">\[<br>u[k] = K_p \cdot e[k] + K_i \cdot T_s \cdot \sum e[k] + K_d \cdot \frac{e[k] &#8211; e[k-1]}{T_s}<br>\]



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float Kp = 1.5, Ki = 0.4, Kd = 0.2;
float Ts = 0.01;
float integral = 0.0;
float previous_error = 0.0;

float compute_control(float error) {
    integral += error * Ts;
    float derivative = (error - previous_error) / Ts;
    previous_error = error;
    return Kp * error + Ki * integral + Kd * derivative;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.5</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.4</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">previous_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (error </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">previous_error</span><span style="color: #D8DEE9FF">) / Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">previous_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.5 Controlador Bang-Bang (On-Off)</h3>



<p class="wp-block-paragraph">Esse é um controlador de dois estados, com atuação total ou nenhuma. É típico em sistemas térmicos e eletromecânicos simples: u(t)={Umaˊx,se&nbsp;e(t)&gt;εUmıˊn,se&nbsp;e(t)&lt;−εs em&nbsp;ação, caso&nbsp;contrário <br>\[<br>u(t) = \begin{cases} U_{\text{máx}}, &amp; \text{se } e(t) &gt; \varepsilon \\ U_{\text{mín}}, &amp; \text{se } e(t) &lt; -\varepsilon \\ \text{sem ação}, &amp; \text{caso contrário} \end{cases}<br>\]



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define U_MAX 1.0
#define U_MIN 0.0
#define EPSILON 0.5

float compute_control(float error) {
    if (error &gt; EPSILON)
        return U_MAX;
    else if (error < -EPSILON)
        return U_MIN;
    else
        return 0.0; // zona morta
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#define U_MAX 1.0</span></span>
<span class="line"><span style="color: #616E88">#define U_MIN 0.0</span></span>
<span class="line"><span style="color: #616E88">#define EPSILON 0.5</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute_control</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">EPSILON</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">U_MAX</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-EPSILON</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">U_MIN</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">else</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">zona</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">morta</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.6 Controle por Modelo (Model Predictive Control &#8211; MPC)</h3>



<p class="wp-block-paragraph">O <strong>Model Predictive Control (MPC)</strong> é uma técnica de controle avançada que utiliza um <strong>modelo matemático da planta</strong> para prever o comportamento futuro do sistema. O controlador resolve, a cada instante de tempo, um <strong>problema de otimização</strong> que minimiza uma função de custo sobre um horizonte de previsão, respeitando restrições do sistema (como limites de atuação e segurança).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Conceito Fundamental</h4>



<p class="wp-block-paragraph">Em vez de reagir apenas ao erro atual, o MPC <strong>prevê os futuros estados do sistema</strong> e calcula a sequência ótima de ações de controle para minimizar o erro futuro.</p>



<p class="wp-block-paragraph">A função de custo típica a ser minimizada é:</p>



<p class="wp-block-paragraph">\[<br>J = \sum_{k=0}^{N_p-1} \left[ (x_k &#8211; x_{\text{ref}})^T Q (x_k &#8211; x_{\text{ref}}) + u_k^T R u_k \right]<br>\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>\(x_k\) = estado previsto no instante kk,</li>



<li>\(x_{\text{ref}}\) = valor de referência,</li>



<li>\(u_k\) = controle aplicado no instante kk,</li>



<li>Q e R = matrizes de ponderação de erro e esforço de controle,</li>



<li>\(N_p\) = horizonte de previsão.</li>
</ul>



<p class="wp-block-paragraph">A predição usa um <strong>modelo do sistema</strong> (tipicamente discreto e linear): </p>



<p class="wp-block-paragraph">\[<br>x_{k+1} = A x_k + B u_k<br>\]



<p class="wp-block-paragraph">O MPC então <strong>escolhe a melhor sequência de controles</strong> </p>



<p class="wp-block-paragraph">\[<br>\{u_0, u_1, &#8230;, u_{N_c-1}\}<br>\]



<p class="wp-block-paragraph"> tal que J seja mínimo, e aplica apenas o <strong>primeiro controle da sequência</strong>, recalculando tudo no próximo passo (controle em tempo real, modo receding horizon).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9f0.png" alt="🧰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Vantagens do MPC</h4>



<ul class="wp-block-list">
<li>Considera <strong>dinâmica futura</strong> da planta;</li>



<li>Suporta <strong>restrições explícitas</strong> (por exemplo: saturação de atuadores, limites físicos);</li>



<li>Pode lidar com <strong>sistemas multivariáveis</strong> com facilidade;</li>



<li>É adequado para sistemas lentos ou com atrasos.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Desvantagens</h4>



<ul class="wp-block-list">
<li>Alto custo computacional (resolve um problema de otimização em tempo real);</li>



<li>Exige um <strong>modelo matemático preciso</strong> do sistema;</li>



<li>Mais difícil de implementar em microcontroladores simples (mas viável com Cortex-M7, ESP32, etc.).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e9.png" alt="🧩" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pseudocódigo em C para MPC Linear Simples</h3>



<p class="wp-block-paragraph">Abaixo está uma estrutura simplificada, ilustrando um MPC linear com horizonte de predição curto, sem restrições explícitas:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define N_P 5     // Horizonte de predição
#define N_U 1     // Horizonte de controle (aplicamos só o 1º controle)
#define STATE_DIM 1
#define INPUT_DIM 1

float A = 1.0f;   // Matriz do modelo (simplificado para escalar)
float B = 0.1f;
float Q = 1.0f;   // Peso do erro
float R = 0.01f;  // Peso do esforço
float x = 0.0f;   // Estado atual
float ref = 1.0f; // Referência

// Simula a predição de N_P passos à frente com diferentes valores de u
float simulate_trajectory(float u) {
    float x_pred = x;
    float cost = 0.0f;

    for (int k = 0; k < N_P; k++) {
        x_pred = A * x_pred + B * u;
        float error = x_pred - ref;
        cost += Q * error * error + R * u * u;
    }

    return cost;
}

// Busca o melhor valor de u entre -1.0 e 1.0 (resolução grosseira)
float mpc_control() {
    float best_u = 0.0f;
    float best_cost = 1e9;

    for (float u = -1.0f; u <= 1.0f; u += 0.1f) {
        float cost = simulate_trajectory(u);
        if (cost < best_cost) {
            best_cost = cost;
            best_u = u;
        }
    }

    return best_u;
}

// Loop de controle
void control_loop() {
    float u = mpc_control();
    apply_control(u);           // Envia para o atuador
    x = update_state(x, u);     // Simula planta ou lê via sensor
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#define N_P 5     // Horizonte de predição</span></span>
<span class="line"><span style="color: #616E88">#define N_U 1     // Horizonte de controle (aplicamos só o 1º controle)</span></span>
<span class="line"><span style="color: #616E88">#define STATE_DIM 1</span></span>
<span class="line"><span style="color: #616E88">#define INPUT_DIM 1</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">A</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Matriz</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">modelo</span><span style="color: #D8DEE9FF"> (simplificado </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">escalar</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">B</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.1</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Q</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Peso</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">erro</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">R</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Peso</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">esforço</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Estado</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">atual</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Referência</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Simula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">predição</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N_P</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">passos</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">à</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">frente</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">com</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">diferentes</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">valores</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">simulate_trajectory</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x_pred</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N_P</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x_pred</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">A</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x_pred</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">B</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x_pred</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ref</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Q</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">R</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cost</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Busca</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">melhor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">entre</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-1.0</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #D8DEE9FF"> (resolução </span><span style="color: #A3BE8C">grosseira</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mpc_control</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">best_u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">best_cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">e9</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-1.0f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.1</span><span style="color: #A3BE8C">f</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">simulate_trajectory</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">u</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">best_cost</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">best_cost</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cost</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">best_u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">best_u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Loop</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controle</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control_loop</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mpc_control</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">apply_control(u</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">           </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Envia</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">atuador</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">update_state</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Simula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">planta</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ou</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">lê</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">via</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sensor</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9ea.png" alt="🧪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Explicação do Pseudocódigo</h3>



<ul class="wp-block-list">
<li>O modelo do sistema é: \(x_{k+1} = A x_k + B u_k\).</li>



<li>A função <code>simulate_trajectory(u)</code> calcula o custo total ao aplicar sempre o mesmo uu durante o horizonte de predição.</li>



<li>O controlador testa vários valores de uu e escolhe o que minimiza o custo.</li>



<li>Isso representa um <strong>controle ótimo com base em predições</strong>, mesmo em um sistema com recursos limitados.</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="611" src="https://mcu.tec.br/wp-content/uploads/2025/03/image-14-1024x611.png" alt="" class="wp-image-237" srcset="https://mcu.tec.br/wp-content/uploads/2025/03/image-14-1024x611.png 1024w, https://mcu.tec.br/wp-content/uploads/2025/03/image-14-300x179.png 300w, https://mcu.tec.br/wp-content/uploads/2025/03/image-14-768x458.png 768w, https://mcu.tec.br/wp-content/uploads/2025/03/image-14-1536x916.png 1536w, https://mcu.tec.br/wp-content/uploads/2025/03/image-14.png 1979w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">simulação do controle preditivo por modelo (MPC) aplicado a um sistema simples:<br><strong>Gráfico superior</strong>: mostra a saída do sistema x  ao longo do tempo, convergindo suavemente até a referência (linha tracejada).<br><strong>Gráfico inferior</strong>: mostra o sinal de controle u  ajustado a cada passo para minimizar o erro futuro.</figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Melhorias possíveis</h3>



<ul class="wp-block-list">
<li>Resolver o problema de otimização usando algoritmos mais rápidos: <strong>gradiente, Newton, QP</strong>;</li>



<li>Suporte a <strong>restrições de entrada e estado</strong>;</li>



<li>Controle multivariável (com matrizes <code>A</code>, <code>B</code>, <code>Q</code>, <code>R</code>);</li>



<li>Integração com bibliotecas lineares como <strong>Eigen</strong> (C++) ou <strong>CMSIS-DSP</strong> (C para ARM).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.7 Controle Adaptativo </h3>



<p class="wp-block-paragraph">O <strong>Controle Adaptativo</strong> é uma técnica projetada para sistemas cujas <strong>características dinâmicas mudam ao longo do tempo</strong> ou não são completamente conhecidas. Diferente do PID e do MPC, que pressupõem modelos fixos ou bem definidos, o controle adaptativo <strong>ajusta seus próprios parâmetros automaticamente</strong> com base na resposta do sistema.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Quando usar Controle Adaptativo?</h3>



<ul class="wp-block-list">
<li>Sistemas com grande <strong>variação de carga</strong> (ex: ventiladores, motores, robôs com carga variável);</li>



<li>Plantas com <strong>dinâmica incerta</strong> ou que muda com o tempo (ex: sistemas térmicos, baterias, processos biológicos);</li>



<li>Ambientes que exigem <strong>autocalibração</strong>, como controle remoto sem conhecimento prévio da planta.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Objetivo</h3>



<p class="wp-block-paragraph">Projetar um controlador que:</p>



<ul class="wp-block-list">
<li><strong>Estime os parâmetros</strong> do sistema em tempo real;</li>



<li>Ajuste os <strong>parâmetros de controle</strong> com base nessas estimativas;</li>



<li>Mantenha <strong>estabilidade e desempenho</strong> diante de variações.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tipos Principais de Controle Adaptativo</h2>



<ol class="wp-block-list">
<li><strong>Modelo de Referência (MRAC – Model Reference Adaptive Control):</strong>
<ul class="wp-block-list">
<li>O controlador ajusta seus parâmetros para que o sistema siga a resposta de um <strong>modelo ideal predefinido</strong>.</li>
</ul>
</li>



<li><strong>Self-Tuning Regulator (STR):</strong>
<ul class="wp-block-list">
<li>Primeiro <strong>identifica os parâmetros da planta</strong>, depois <strong>sintetiza o controlador ótimo</strong> com base nesses parâmetros estimados.</li>
</ul>
</li>



<li><strong>Controle com ganho variável (Gain Scheduling):</strong>
<ul class="wp-block-list">
<li>Parâmetros do controlador mudam com base em <strong>condições de operação medidas</strong> (ex: velocidade, temperatura).</li>
</ul>
</li>



<li><strong>Redes neurais ou lógica fuzzy adaptativa:</strong>
<ul class="wp-block-list">
<li>Algoritmos de aprendizado (machine learning) para mapear e ajustar controles não lineares.</li>
</ul>
</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d0.png" alt="📐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Exemplo Simples: MRAC com Atualização de Ganhos Online</h3>



<p class="wp-block-paragraph">Dado o sistema: \(x(t)+bu(t)\dot{x}(t) = a x(t) + b u(t)\)</p>



<p class="wp-block-paragraph">Queremos que ele siga o modelo de referência: \(\dot{x}_m(t) = a_m x_m(t) + b_m r(t)\)</p>



<p class="wp-block-paragraph">A lei de controle adaptativa (simplificada) pode ser: \(u(t) = \theta(t) \cdot x(t)\)</p>



<p class="wp-block-paragraph">E os parâmetros θ(t)\theta(t) são ajustados com base no erro de seguimento: \(e(t) = x(t) &#8211; x_m(t)\)</p>



<p class="wp-block-paragraph">A <strong>regra de adaptação</strong> baseada em Lyapunov pode ser: \(\frac{d\theta(t)}{dt} = -\gamma \cdot e(t) \cdot x(t)\)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9ee.png" alt="🧮" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pseudocódigo em C (Versão Discreta)</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="typedef struct {
    float theta;     // Ganho adaptativo
    float gamma;     // Taxa de aprendizagem
    float a_ref;     // Parâmetro do modelo de referência
    float b_ref;
    float x;         // Estado do sistema real
    float x_ref;     // Estado do modelo de referência
    float Ts;        // Tempo de amostragem
} MRAC_Controller;

void mrac_init(MRAC_Controller* ctrl, float gamma, float a_ref, float b_ref, float Ts) {
    ctrl-&gt;theta = 0.0f;
    ctrl-&gt;gamma = gamma;
    ctrl-&gt;a_ref = a_ref;
    ctrl-&gt;b_ref = b_ref;
    ctrl-&gt;x = 0.0f;
    ctrl-&gt;x_ref = 0.0f;
    ctrl-&gt;Ts = Ts;
}

float mrac_update(MRAC_Controller* ctrl, float reference) {
    // Modelo de referência
    float dx_ref = ctrl-&gt;a_ref * ctrl-&gt;x_ref + ctrl-&gt;b_ref * reference;
    ctrl-&gt;x_ref += dx_ref * ctrl-&gt;Ts;

    // Erro de seguimento
    float error = ctrl-&gt;x - ctrl-&gt;x_ref;

    // Atualização do ganho adaptativo (gradiente descendente)
    ctrl-&gt;theta -= ctrl-&gt;gamma * error * ctrl-&gt;x * ctrl-&gt;Ts;

    // Controle aplicado
    float u = ctrl-&gt;theta * ctrl-&gt;x;

    // Simula a planta real (dinâmica desconhecida, aqui exemplo fixo)
    float a = -0.5f, b = 1.0f;
    float dx = a * ctrl-&gt;x + b * u;
    ctrl-&gt;x += dx * ctrl-&gt;Ts;

    return u;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">theta</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ganho</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">adaptativo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">gamma</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Taxa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">aprendizagem</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a_ref</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Parâmetro</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">modelo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">referência</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">b_ref</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">         </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Estado</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sistema</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x_ref</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Estado</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">modelo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">referência</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Tempo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">amostragem</span></span>
<span class="line"><span style="color: #D8DEE9FF">} MRAC_Controller;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mrac_init</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">MRAC_Controller*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">gamma,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a_ref,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">b_ref,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;theta</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;gamma</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">gamma</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;a_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a_ref</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;b_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">b_ref</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;x_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;Ts</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mrac_update</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">MRAC_Controller*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">reference</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Modelo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">referência</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dx_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">a_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">b_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">reference</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;x_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dx_ref</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Erro</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">seguimento</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x_ref</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Atualização</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ganho</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">adaptativo</span><span style="color: #D8DEE9FF"> (gradiente </span><span style="color: #A3BE8C">descendente</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;theta</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">gamma</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Controle</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">aplicado</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">theta</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Simula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">planta</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #D8DEE9FF"> (dinâmica </span><span style="color: #A3BE8C">desconhecida,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">aqui</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">exemplo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fixo</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-0.5f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dx</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ctrl-&gt;x</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ctrl</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Comportamento Esperado</h3>



<ul class="wp-block-list">
<li>A cada passo, o parâmetro θ é ajustado de forma a minimizar o erro entre o sistema real e o modelo de referência;</li>



<li>Ao longo do tempo, o sistema &#8220;aprende&#8221; a resposta desejada;</li>



<li>A estabilidade é garantida se a taxa de adaptação γ for bem escolhida.</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="826" src="https://mcu.tec.br/wp-content/uploads/2025/03/image-15-1024x826.png" alt="" class="wp-image-242" srcset="https://mcu.tec.br/wp-content/uploads/2025/03/image-15-1024x826.png 1024w, https://mcu.tec.br/wp-content/uploads/2025/03/image-15-300x242.png 300w, https://mcu.tec.br/wp-content/uploads/2025/03/image-15-768x620.png 768w, https://mcu.tec.br/wp-content/uploads/2025/03/image-15-1536x1239.png 1536w, https://mcu.tec.br/wp-content/uploads/2025/03/image-15.png 1958w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">gráficos da simulação do controlador adaptativo MRAC:<br><strong>Gráfico superior:</strong> mostra como a saída do sistema real (linha contínua) converge ao longo do tempo para a trajetória do modelo de referência (linha tracejada), mesmo sem conhecimento prévio dos parâmetros da planta.<br><strong>Gráfico do meio:</strong> representa o erro de seguimento entre o sistema real e o modelo ideal. O erro tende a zero à medida que o controlador se ajusta.<br><strong>Gráfico inferior:</strong> mostra a evolução do ganho adaptativo θ(t), que é ajustado dinamicamente para manter o controle ideal.</figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9f0.png" alt="🧰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Vantagens do Controle Adaptativo</h3>



<ul class="wp-block-list">
<li><strong>Alta flexibilidade</strong> frente a incertezas e variações;</li>



<li>Requer <strong>menos conhecimento prévio</strong> da planta;</li>



<li>Potencial de <strong>autoajuste contínuo</strong> durante a operação.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Desvantagens</h3>



<ul class="wp-block-list">
<li>Mais difícil de <strong>analisar e validar formalmente</strong>;</li>



<li>Pode ser sensível a ruídos, atrasos ou saturações;</li>



<li>Requer <strong>cuidados com estabilidade</strong> (sobretudo em sistemas rápidos).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.8 Controle Ótimo Linear Quadrático (LQR – Linear Quadratic Regulator)</h3>



<p class="wp-block-paragraph">O LQR é um algoritmo de controle ótimo que busca minimizar uma função de custo quadrática, considerando simultaneamente a resposta do sistema e o esforço de controle. Ele se baseia em um modelo de estado da planta (forma matricial) e é projetado para sistemas lineares com tempo contínuo ou discreto.</p>



<p class="wp-block-paragraph">A função de custo a ser minimizada é: </p>



<p class="wp-block-paragraph">\[<br>J = \int_0^\infty (x^T Q x + u^T R u)\,dt<br>\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>x: vetor de estados do sistema;</li>



<li>u: vetor de controle;</li>



<li>Q: matriz de ponderação dos estados (penaliza desvios);</li>



<li>R: matriz de ponderação do esforço de controle.</li>
</ul>



<p class="wp-block-paragraph">O controlador LQR calcula o vetor de controle como: \(\(u(t) = -K \cdot x(t)\)\)</p>



<p class="wp-block-paragraph">onde K é a matriz de ganhos ótima obtida pela resolução da equação de Riccati.</p>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Otimização rigorosa de desempenho e energia;</li>



<li>Estável por construção;</li>



<li>Fácil de estender para sistemas multivariáveis.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Exige conhecimento preciso do modelo matemático;</li>



<li>Pouco robusto a variações bruscas na planta.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações típicas:</strong></p>



<ul class="wp-block-list">
<li>Controle de veículos autônomos (tração e frenagem);</li>



<li>Estabilização de drones;</li>



<li>Robótica de precisão.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4.9 Controle Robusto H∞ (H-infinito)</h3>



<p class="wp-block-paragraph">O controle H∞H_\infty é uma técnica voltada para garantir <strong>robustez</strong> contra incertezas no modelo da planta e rejeição de perturbações externas. Em vez de minimizar um custo específico (como no LQR), o objetivo é minimizar o <strong>ganho máximo</strong> da função de transferência sensibilidade do sistema, assegurando desempenho mesmo sob as piores condições.</p>



<p class="wp-block-paragraph">Ele é formulado como um problema de otimização de normas matriciais, buscando um controlador \(K(s)\) tal que: </p>



<p class="wp-block-paragraph">\[<br>\| T_{zw}(s) \|_{\infty} &lt; \gamma<br>\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\(T_{zw}(s)\): função de transferência entre perturbações w e saídas z;</li>



<li>\(γ\gamma\): ganho máximo admissível.</li>
</ul>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Garante robustez explícita contra incertezas modeladas;</li>



<li>Adequado para sistemas sujeitos a perturbações e ruído.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Complexidade matemática e computacional elevada;</li>



<li>Requer métodos de síntese numérica (como LMI – Linear Matrix Inequalities).</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações típicas:</strong></p>



<ul class="wp-block-list">
<li>Controle de sistemas aeroespaciais;</li>



<li>Estabilização de sistemas instáveis com ruído;</li>



<li>Sistemas com requisitos de segurança rigorosos.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Esses dois métodos — LQR e \(H_\infty\) — fazem parte do campo do <strong>controle moderno</strong>, no qual se representa o sistema na forma de estado e se explora otimização, robustez e propriedades matemáticas formais.</p>



<p class="wp-block-paragraph">Ambos requerem modelagem precisa e ferramentas de cálculo avançado, como MATLAB, Scilab, Octave ou bibliotecas científicas específicas em C/C++ (por exemplo, Armadillo ou Eigen).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5. Consequências e Comparação Entre os Métodos de Controle de Loop Fechado</h2>



<p class="wp-block-paragraph">Cada algoritmo de controle de loop fechado traz consigo um conjunto distinto de características, implicações práticas e limitações. A escolha adequada do controlador não depende apenas do desempenho teórico, mas também do ambiente de aplicação, do custo computacional e da robustez exigida. Abaixo, discutimos as principais consequências de adotar cada tipo de controlador.</p>



<h3 class="wp-block-heading">5.1 Controladores Clássicos (P, PI, PD, PID)</h3>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Simples de implementar e ajustar;</li>



<li>Amplamente utilizados em sistemas industriais e embarcados;</li>



<li>PID pode ser implementado mesmo em microcontroladores simples.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Não oferecem robustez explícita;</li>



<li>Não consideram restrições do sistema (saturação, limites físicos);</li>



<li>Não têm otimização formal de desempenho.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações Típicas:</strong></p>



<ul class="wp-block-list">
<li>Controle de temperatura, velocidade, pressão;</li>



<li>Motores DC e servo motores;</li>



<li>Fontes chaveadas, HVAC, automação básica.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5.2 Bang-Bang (On-Off)</h3>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Simplicidade extrema (usa apenas decisões binárias);</li>



<li>Alta robustez em aplicações com grande histerese.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Pode gerar oscilação e desgaste mecânico;</li>



<li>Pouco preciso;</li>



<li>Inadequado para sistemas dinâmicos rápidos.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações Típicas:</strong></p>



<ul class="wp-block-list">
<li>Termostatos, acionamento de relés, controle hidráulico básico;</li>



<li>Controle de bombas e aquecedores simples.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5.3 Controle Ótimo (LQR)</h3>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Otimiza a estabilidade e o esforço de controle;</li>



<li>Excelente para sistemas com múltiplos estados;</li>



<li>Garante desempenho suave e previsível.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Requer modelo matemático preciso;</li>



<li>Complexidade de projeto e cálculo da matriz de ganhos KK;</li>



<li>Dificuldade de adaptação em tempo real.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações Típicas:</strong></p>



<ul class="wp-block-list">
<li>Drones, veículos autônomos, sistemas inerciais;</li>



<li>Robôs manipuladores e estabilizadores de câmera.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5.4 Controle Robusto \(H_\infty\)</h3>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Forte resistência a incertezas na planta;</li>



<li>Ideal para sistemas críticos e inseguros;</li>



<li>Considera perturbações explícitas e desempenho em condições extremas.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Projeto matematicamente complexo;</li>



<li>Elevado custo computacional;</li>



<li>Pouco utilizado em sistemas embarcados com recursos limitados.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações Típicas:</strong></p>



<ul class="wp-block-list">
<li>Controle aeroespacial, defesa, sistemas navais;</li>



<li>Equipamentos de missão crítica ou ambientes hostis.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5.5 Controle Adaptativo</h3>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Ajusta-se automaticamente às mudanças da planta;</li>



<li>Ideal para sistemas com comportamento não estacionário;</li>



<li>Pode manter desempenho mesmo em casos imprevistos.</li>
</ul>



<p class="wp-block-paragraph"><strong>Desvantagens:</strong></p>



<ul class="wp-block-list">
<li>Maior complexidade computacional e teórica;</li>



<li>Pode ter instabilidades se mal projetado;</li>



<li>Difícil de validar com testes formais.</li>
</ul>



<p class="wp-block-paragraph"><strong>Aplicações Típicas:</strong></p>



<ul class="wp-block-list">
<li>Máquinas CNC com variação de carga;</li>



<li>Controle inteligente de motores;</li>



<li>Sistemas embarcados em ambientes variáveis.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5.6 Comparação Geral</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Algoritmo</th><th>Fácil de Implementar</th><th>Robusto</th><th>Otimizado</th><th>Exige Modelo</th><th>Baixo Custo Computacional</th></tr></thead><tbody><tr><td>P</td><td>Sim</td><td>Baixo</td><td>Não</td><td>Não</td><td>Sim</td></tr><tr><td>PI</td><td>Sim</td><td>Médio</td><td>Parcial</td><td>Não</td><td>Sim</td></tr><tr><td>PID</td><td>Sim</td><td>Médio</td><td>Parcial</td><td>Não</td><td>Sim</td></tr><tr><td>Bang-Bang</td><td>Sim</td><td>Alto</td><td>Não</td><td>Não</td><td>Sim</td></tr><tr><td>LQR</td><td>Não</td><td>Médio</td><td>Sim</td><td>Sim</td><td>Médio</td></tr><tr><td>H∞</td><td>Não</td><td>Muito Alto</td><td>Sim</td><td>Sim</td><td>Alto</td></tr><tr><td>Adaptativo</td><td>Não</td><td>Alto</td><td>Sim</td><td>Não Necessário</td><td>Médio-Alto</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Em resumo, <strong>controladores clássicos</strong> continuam sendo a melhor escolha para aplicações <strong>simples e eficientes</strong>, enquanto <strong>controladores ótimos e robustos</strong> são ideais para <strong>sistemas complexos</strong>, com <strong>grandes incertezas</strong> ou que requerem <strong>máxima confiabilidade</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">6. Estratégias de Implementação em Sistemas Embarcados</h2>



<p class="wp-block-paragraph">Implementar algoritmos de controle de loop fechado em sistemas embarcados exige atenção a diversos fatores práticos: uso eficiente do tempo de CPU, precisão numérica, uso de interrupções e recursos periféricos como ADCs, timers e PWMs. Esta seção apresenta estratégias eficazes para tornar os algoritmos aplicáveis em microcontroladores como STM32, AVR, ESP32, entre outros.</p>



<h3 class="wp-block-heading">6.1 Amostragem Periódica</h3>



<p class="wp-block-paragraph">A base do controle digital é o cálculo periódico do sinal de controle. Para isso, o ideal é configurar um <strong>timer de hardware</strong> que dispare uma <strong>interrupção periódica</strong> a cada TsT_s milissegundos. Essa interrupção deve chamar a função do controlador.</p>



<p class="wp-block-paragraph"><strong>Exemplo (pseudocódigo para STM32 HAL):</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim-&gt;Instance == TIM3) { // Timer configurado para 10 ms
        control_loop();           // Executa o PID
    }
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">HAL_TIM_PeriodElapsedCallback</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">TIM_HandleTypeDef</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #A3BE8C">htim</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">htim-&gt;Instance</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">TIM3</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Timer</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">configurado</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ms</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">control_loop</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">           </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Executa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PID</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">6.2 Leitura de Sensores (ADC)</h3>



<p class="wp-block-paragraph">A maioria das variáveis de processo (como corrente, temperatura ou velocidade) é medida via <strong>ADC</strong> (Conversor Analógico-Digital). A leitura deve ser feita no início do loop de controle.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float read_sensor() {
    HAL_ADC_Start(&amp;hadc1);
    HAL_ADC_PollForConversion(&amp;hadc1, 10);
    uint32_t raw = HAL_ADC_GetValue(&amp;hadc1);
    return (float)raw * SCALE_FACTOR;  // converter para unidade real
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">read_sensor</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">HAL_ADC_Start(</span><span style="color: #ECEFF4">&amp;</span><span style="color: #88C0D0">hadc1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">HAL_ADC_PollForConversion(</span><span style="color: #ECEFF4">&amp;</span><span style="color: #88C0D0">hadc1,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">raw</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">HAL_ADC_GetValue</span><span style="color: #ECEFF4">(&amp;</span><span style="color: #88C0D0">hadc1</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (float)raw </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> SCALE_FACTOR</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">converter</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unidade</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">6.3 Escrita no Atuador (PWM ou DAC)</h3>



<p class="wp-block-paragraph">O sinal de controle calculado deve ser convertido em uma ação física. Nos sistemas embarcados, isso é feito tipicamente via:</p>



<ul class="wp-block-list">
<li><strong>PWM</strong> (modulação por largura de pulso), para controlar motores, aquecedores, etc.</li>



<li><strong>DAC</strong> (Conversor Digital-Analógico), para gerar tensões analógicas em sistemas de controle contínuo.</li>
</ul>



<p class="wp-block-paragraph"><strong>Exemplo com PWM:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="void write_actuator(float control) {
    if (control < 0) control = 0;
    if (control &gt; 100) control = 100;
    __HAL_TIM_SET_COMPARE(&amp;htim2, TIM_CHANNEL_1, control);  // Duty cycle (%)
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">write_actuator</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">control</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> control = 0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">control</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> control = 100</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">__HAL_TIM_SET_COMPARE(</span><span style="color: #ECEFF4">&amp;</span><span style="color: #88C0D0">htim2,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">TIM_CHANNEL_1,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Duty</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cycle</span><span style="color: #D8DEE9FF"> (%)</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">6.4 Cálculo Seguro do Controle</h3>



<ul class="wp-block-list">
<li>Use <strong>variáveis <code>float</code> ou <code>fixed-point</code></strong> dependendo da arquitetura e necessidade de precisão.</li>



<li>Implemente <strong>limites no integrador (anti-windup)</strong> para evitar saturações.</li>



<li>Proteja o cálculo com <strong>&#8220;clipping&#8221;</strong> de entrada e saída.</li>
</ul>



<pre class="wp-block-code"><code>if (integral &gt; INTEGRAL_MAX) integral = INTEGRAL_MAX;
if (integral &lt; INTEGRAL_MIN) integral = INTEGRAL_MIN;
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">6.5 Filtros para Derivada</h3>



<p class="wp-block-paragraph">O termo derivativo do PID é sensível a ruído de medição. Para suavizá-lo, use <strong>filtros digitais</strong>: </p>



<p class="wp-block-paragraph">\[<br>D(t) = K_d \cdot \frac{d}{dt} \left( y_{\text{filtrado}}(t) \right)<br>\]



<p class="wp-block-paragraph">Um filtro passa-baixa simples pode ser usado para suavizar a variável medida:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="float low_pass_filter(float current, float previous, float alpha) {
    return alpha * current + (1 - alpha) * previous;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">low_pass_filter</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">current,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">previous,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">alpha</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">alpha</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">current</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> (1 </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">alpha</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> previous</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">6.6 Estrutura Modular</h3>



<p class="wp-block-paragraph">Divida o controle em três blocos principais:</p>



<ol class="wp-block-list">
<li><strong>Amostragem da variável (sensor)</strong></li>



<li><strong>Cálculo do controle</strong></li>



<li><strong>Aplicação da saída (atuador)</strong></li>
</ol>



<p class="wp-block-paragraph">Isso facilita manutenção, testes e mudanças de controlador. Também permite reaproveitar o mesmo &#8220;esqueleto&#8221; para múltiplos tipos de controlador (PID, LQR, etc.).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">6.7 Considerações para Controladores Avançados</h3>



<p class="wp-block-paragraph">Para algoritmos como <strong>LQR, MPC ou Adaptativo</strong>, é necessário:</p>



<ul class="wp-block-list">
<li>Estruturas de matriz (como arrays bidimensionais);</li>



<li>Uso de bibliotecas como <a href="https://arm-software.github.io/CMSIS_5/DSP/html/index.html">CMSIS-DSP</a> (para ARM Cortex-M);</li>



<li>Alocação estática de memória (evitar <code>malloc</code>);</li>



<li>Processamento fora da interrupção (por ex., em tarefa de RTOS).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Essas estratégias visam garantir <strong>baixa latência</strong>, <strong>alta precisão</strong>, <strong>tempo real garantido</strong> e <strong>robustez frente a falhas</strong> – requisitos essenciais em controle embarcado.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7. Padrões Relacionados e Modelos de Projeto</h2>



<p class="wp-block-paragraph">A implementação de algoritmos de controle em sistemas embarcados pode se beneficiar enormemente do uso de <strong>padrões de projeto (design patterns)</strong>. Esses padrões ajudam a estruturar o código de forma clara, reutilizável e extensível, permitindo manutenção mais fácil e maior confiabilidade, especialmente em sistemas de tempo real.</p>



<p class="wp-block-paragraph">Abaixo, listamos os principais padrões relacionados ao desenvolvimento de controladores de loop fechado:</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.1 Strategy Pattern (Padrão Estratégia)</h3>



<p class="wp-block-paragraph">Esse é um dos mais diretamente aplicáveis ao controle. O Strategy Pattern permite que diferentes algoritmos de controle (PID, Bang-Bang, LQR, etc.) sejam intercambiáveis em tempo de execução, desde que implementem uma interface comum.</p>



<p class="wp-block-paragraph"><strong>Aplicação:</strong> Você define uma interface <code>ControlAlgorithm</code> com a função <code>compute(float error)</code>. Cada algoritmo implementa essa função de forma diferente.</p>



<p class="wp-block-paragraph"><strong>Vantagens:</strong></p>



<ul class="wp-block-list">
<li>Facilita a troca dinâmica do controlador;</li>



<li>Permite testes A/B de algoritmos com a mesma infraestrutura de hardware;</li>



<li>Reutilização de código.</li>
</ul>



<p class="wp-block-paragraph"><strong>Exemplo em C:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="typedef float (*control_function_t)(float error);

typedef struct {
    control_function_t compute;
} ControlStrategy;

ControlStrategy pid_controller = { .compute = pid_compute };
ControlStrategy bangbang_controller = { .compute = bangbang_compute };

// No loop de controle:
float u = controller.compute(error);
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> (*control_function_t)</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">control_function_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} ControlStrategy;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">ControlStrategy</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_controller</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.compute</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_compute</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">ControlStrategy</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bangbang_controller</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.compute</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bangbang_compute</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">No</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">loop</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controle:</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controller.compute</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">error</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.2 State Pattern (Padrão de Estado)</h3>



<p class="wp-block-paragraph">Útil em sistemas com diferentes <strong>modos operacionais</strong>, como controle ativo, standby, segurança, etc. Cada estado pode usar um algoritmo de controle diferente, ou configurar parâmetros do PID de forma distinta.</p>



<p class="wp-block-paragraph"><strong>Aplicação:</strong> Você modela o sistema como uma <strong>máquina de estados</strong>, e cada estado contém um algoritmo ou conjunto de parâmetros.</p>



<p class="wp-block-paragraph"><strong>Exemplo:</strong></p>



<ul class="wp-block-list">
<li>Estado “Aquecendo” usa PID.</li>



<li>Estado “Manutenção” usa Bang-Bang.</li>



<li>Estado “Falha” desliga a saída.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.3 Singleton Pattern</h3>



<p class="wp-block-paragraph">Em muitos sistemas embarcados, o controlador é um único recurso global. O padrão Singleton garante que apenas uma instância do controlador esteja ativa e acessível globalmente (com cuidado em sistemas com multitarefa).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.4 Observer Pattern</h3>



<p class="wp-block-paragraph">Ideal para desacoplar o controlador dos sensores e atuadores. O controlador pode ser notificado quando um novo valor de sensor é lido (por exemplo, em RTOS ou eventos baseados em filas).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.5 Command Pattern</h3>



<p class="wp-block-paragraph">Útil quando se deseja encapsular comandos de controle, por exemplo para registrar comandos enviados, desfazer ações (undo), ou aplicar sequências de controle programadas.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7.6 Aplicação Combinada com RTOS</h3>



<p class="wp-block-paragraph">Em sistemas com sistemas operacionais de tempo real (como FreeRTOS, Zephyr ou ThreadX), o controlador pode ser implementado como uma <strong>tarefa</strong> que bloqueia esperando um semáforo ou notificação de timer. Os padrões citados ajudam a estruturar essa tarefa:</p>



<ul class="wp-block-list">
<li>O Strategy define a lógica de controle;</li>



<li>O Observer permite que a tarefa reaja a eventos;</li>



<li>O State define modos de operação com diferentes estratégias.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Exemplo Integrado:</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="// Estrutura do controlador com Strategy
typedef struct {
    control_function_t compute;
    float Kp, Ki, Kd;
} PIDController;

float pid_compute(PIDController* pid, float error) {
    // implementação PID com base nos parâmetros
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Estrutura</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controlador</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">com</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Strategy</span></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">control_function_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">compute</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} PIDController;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_compute</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">PIDController*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">implementação</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PID</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">com</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">base</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">nos</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">parâmetros</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><strong>Benefícios de usar padrões de projeto no controle:</strong></p>



<ul class="wp-block-list">
<li><strong>Clareza</strong>: separa claramente responsabilidades (cálculo, interface, hardware);</li>



<li><strong>Escalabilidade</strong>: facilita a evolução do sistema com novos algoritmos ou estados;</li>



<li><strong>Testabilidade</strong>: permite testes unitários isolados para cada componente;</li>



<li><strong>Reutilização</strong>: mesmo controlador pode ser usado em vários projetos.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">8. Modelo de Amostragem: Exemplo Completo de Implementação PID em C</h2>



<p class="wp-block-paragraph">A seguir está um modelo funcional e modularizado de controlador PID em C. Ele pode ser adaptado facilmente para microcontroladores como STM32, AVR, ESP32 ou outros, e segue as boas práticas discutidas nas seções anteriores, incluindo encapsulamento, separação de responsabilidades e proteção contra saturações.</p>



<h3 class="wp-block-heading">8.1 Arquivo de Cabeçalho – <code>pid.h</code></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#ifndef PID_H
#define PID_H

typedef struct {
    float Kp;
    float Ki;
    float Kd;
    float Ts;             // Tempo de amostragem em segundos
    float integral;
    float prev_error;
    float output_min;
    float output_max;
} PIDController;

// Inicializa os parâmetros do PID
void pid_init(PIDController* pid, float Kp, float Ki, float Kd, float Ts, float min, float max);

// Executa o cálculo do PID
float pid_compute(PIDController* pid, float setpoint, float measurement);

#endif
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#ifndef PID_H</span></span>
<span class="line"><span style="color: #616E88">#define PID_H</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">             </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Tempo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">amostragem</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">em</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">segundos</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">integral</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">prev_error</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">output_min</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">output_max</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} PIDController;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Inicializa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">os</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">parâmetros</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PID</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_init</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">PIDController*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">min,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">max</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Executa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cálculo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PID</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_compute</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">PIDController*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">measurement</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">#endif</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">8.2 Arquivo de Implementação – <code>pid.c</code></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include &quot;pid.h&quot;

void pid_init(PIDController* pid, float Kp, float Ki, float Kd, float Ts, float min, float max) {
    pid-&gt;Kp = Kp;
    pid-&gt;Ki = Ki;
    pid-&gt;Kd = Kd;
    pid-&gt;Ts = Ts;
    pid-&gt;integral = 0.0f;
    pid-&gt;prev_error = 0.0f;
    pid-&gt;output_min = min;
    pid-&gt;output_max = max;
}

float pid_compute(PIDController* pid, float setpoint, float measurement) {
    float error = setpoint - measurement;
    pid-&gt;integral += error * pid-&gt;Ts;

    // Anti-windup
    if (pid-&gt;integral &gt; pid-&gt;output_max) pid-&gt;integral = pid-&gt;output_max;
    if (pid-&gt;integral < pid-&gt;output_min) pid-&gt;integral = pid-&gt;output_min;

    float derivative = (error - pid-&gt;prev_error) / pid-&gt;Ts;
    pid-&gt;prev_error = error;

    float output = pid-&gt;Kp * error + pid-&gt;Ki * pid-&gt;integral + pid-&gt;Kd * derivative;

    // Saturação da saída
    if (output &gt; pid-&gt;output_max) output = pid-&gt;output_max;
    if (output < pid-&gt;output_min) output = pid-&gt;output_min;

    return output;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &quot;pid.h&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_init</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">PIDController*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">min,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">max</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;Ts</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;prev_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;output_min</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">min</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;output_max</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">max</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_compute</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">PIDController*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">measurement</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">measurement</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Anti-windup</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pid-&gt;integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">output_max</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">integral = pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">output_max</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pid-&gt;integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">output_min</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">integral = pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">output_min</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (error </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">prev_error</span><span style="color: #D8DEE9FF">) / pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">Ts</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid-&gt;prev_error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">output</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">derivative</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Saturação</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">saída</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">output</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">output_max</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> output = pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">output_max</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">output</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #D8DEE9FF">-</span><span style="color: #81A1C1">&gt;</span><span style="color: #A3BE8C">output_min</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> output = pid-</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">output_min</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">output</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">8.3 Exemplo de Uso – <code>main.c</code></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include <stdio.h&gt;
#include &quot;pid.h&quot;

// Simulação de sensor e atuador
float read_sensor() {
    static float y = 0.0f;
    return y;
}

void write_actuator(float control_signal) {
    printf(&quot;Controle aplicado: %.2f\n&quot;, control_signal);
}

int main() {
    PIDController pid;
    pid_init(&amp;pid, 2.0f, 1.0f, 0.5f, 0.01f, 0.0f, 100.0f);  // Kp, Ki, Kd, Ts, min, max

    float setpoint = 50.0f;  // Valor desejado
    float process_value = 0.0f;

    for (int i = 0; i < 100; i++) {
        process_value = read_sensor();  // Aqui pode ser ADC
        float u = pid_compute(&amp;pid, setpoint, process_value);
        write_actuator(u);              // Aqui pode ser PWM
        // Simula atualização da variável controlada (pode incluir dinâmica)
    }

    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &lt;stdio.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &quot;pid.h&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Simulação</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sensor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">atuador</span></span>
<span class="line"><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">read_sensor</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">y</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">write_actuator</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control_signal</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;Controle aplicado: %.2f\n&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">control_signal</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">PIDController</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">pid_init(</span><span style="color: #ECEFF4">&amp;</span><span style="color: #88C0D0">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.0</span><span style="color: #A3BE8C">f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.0</span><span style="color: #A3BE8C">f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.5</span><span style="color: #A3BE8C">f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #A3BE8C">f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100.0</span><span style="color: #A3BE8C">f</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kp,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ki,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Kd,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Ts,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">min,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">max</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">50.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">desejado</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">process_value</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">process_value</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">read_sensor</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Aqui</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pode</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ser</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ADC</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pid_compute</span><span style="color: #ECEFF4">(&amp;</span><span style="color: #88C0D0">pid,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">setpoint,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">process_value</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">write_actuator(u</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">              </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Aqui</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pode</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ser</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PWM</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Simula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">atualização</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">variável</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">controlada</span><span style="color: #D8DEE9FF"> (pode </span><span style="color: #A3BE8C">incluir</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dinâmica</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">8.4 Como Adaptar</h3>



<ul class="wp-block-list">
<li><strong>Em tempo real:</strong> coloque <code>pid_compute()</code> em uma ISR de timer (ex: a cada 10 ms).</li>



<li><strong>Leitura real:</strong> substitua <code>read_sensor()</code> por leitura via ADC (HAL ou bare-metal).</li>



<li><strong>Saída real:</strong> use <code>write_actuator()</code> com PWM, DAC ou GPIO para ativar o atuador.</li>



<li><strong>RTOS:</strong> execute o controle em uma tarefa periódica com prioridade adequada.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">8.5 Extensões Possíveis</h3>



<ul class="wp-block-list">
<li>Adicionar <strong>limites de velocidade</strong> na saída (<code>du/dt</code>);</li>



<li>Incorporar <strong>filtro na entrada</strong> (sensor ruidoso);</li>



<li>Suporte a <strong>estratégias de controle alternativas</strong> (via ponteiro de função ou enum);</li>



<li>Log de dados e interface de monitoramento serial.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Conclusão do Modelo</h3>



<p class="wp-block-paragraph">Este exemplo serve como base robusta para <strong>qualquer aplicação embarcada com controle de malha fechada</strong>. Com pequenas alterações, pode ser usado para sistemas de corrente, temperatura, velocidade, posição, entre outros — tanto em aplicações industriais quanto acadêmicas ou hobby.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Se você conhece ou desenvolveu um algoritmo de controle de loop fechado alternativo — seja uma variação do PID, um controlador adaptativo ou mesmo uma abordagem inovadora baseada em inteligência artificial — convidamos você a colaborar com este conteúdo! Compartilhe sua ideia e o código explicando sua lógica por meio de um <a href="https://gist.github.com/">GitHub Gist</a>, e envie o link nos comentários ou entre em contato. Sua contribuição poderá enriquecer ainda mais este guia e ajudar outros desenvolvedores e engenheiros na criação de sistemas de controle mais eficientes e criativos.</p><p>The post <a href="https://mcu.tec.br/algoritimos/algoritmos-de-controle-de-loop-fechado-guia-completo-com-pid-e-exemplos-em-c/">Algoritmos de Controle de Loop Fechado: Guia Completo com PID e Exemplos em C</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">202</post-id>	</item>
	</channel>
</rss>
