DAS5306: Informática Industrial II

Trabalhos para 2006/2

Trabalhos entregues após a data estipulada perdem 10% da nota máxima
por dia de atraso, inclusive sábados e domingos.

Trabalhos entregues no dia correto mas depois do horário de aula também
perdem 10% da nota máxima.

Apresentações individuais podem ser solicitadas.

Uma sugestão para quem só tem Windows em casa é usar o MinGW.


T1 - Trabalho de revisão da linguagem C

Ler do disco um arquivo composto por cerca de 10.000 registros. Cada registro é do tipo

struct aluno{
        char nome[40];
        long matricula;
        double media;
        char sexo;
        int aprovado;
};

O programa para gerar os arquivos é o gerador.c .

Os registros estão colocados no arquivo um atrás do outro, em ordem aleatória.

O arquivo deve ser lido completamente e construída uma tabela hash na memória
principal, sendo usado o campo matricula como chave de busca.

O programa receberá na linha de comando 3 números de matrícula, e deverá
escrever na tela os dados referentes a estes 3 alunos, caso estejam na tabela.
O primeiro argumento na linha de comando é o arquivo de dados a ser lido.
Por exemplo:

----------------------------------------------------------------------------------------

$ trabalho  cadastro.dat  12345  98765  2121212

ALUNO 12345
Rômulo Silva de Olliveira
9.9
m
2000

ALUNO 98765
--- não encontrado ---

ALUNO 2121212
Jean-Marie Farines
9.9
m
1999

----------------------------------------------------------------------------------------

Em seguida, o programa deverá listar na tela os nomes de todos os alunos, em
ordem alfabética. Pode usar a função qsort() da biblioteca, como em qsort.c .

A tabela hash deverá ser implementada no próprio programa, entretanto a ordenação poderá
usar rotinas da biblioteca do C.

É obrigatório usar o tratamento de colisão apresentado no exemplo tabhash.c
da página da disciplina.

T2 - Trabalho sobre controlador discreto

Considere o problema da Linha de Produção de Cervejas, como descrito no
capítulo 3 da apostila do Prof. Cury sobre "Teoria de Controle Supervisório
de Sistemas a Eventos Discretos", página 20.

http://www.das.ufsc.br/~cury/cursos/apostila.pdf

O objetivo neste trabalho é implementar um controlador para maximizar a
produção da planta, ou seja, manter todas as estações da linha
trabalhando simultaneamente a maior parte do tempo.

Os seguintes arquivos estão disponíveis:

controlador3.c    Exemplo do programa controlador a ser feito

envasilhamento3.h    Descrição das rotinas disponíveis no simulador da planta

envasilhamento3.c    Simulador da planta

Escrever um novo controlador3.c que seja automático (o fornecido é manual) e que
maximize a produtividade da planta, considerando a produção de um lote de N garrafas.

Comandos do controlador manual:
e - avança esteira
a - liga atuador
b - liga a bomba
t - liga o tampador
r - liga o robô

Todos eles desligam após realizar um ciclo de trabalho.

As rotinas do tipo acionaXYZ retornam -1 quando o dispositivo
está em operação, neste caso um novo pedido de acionamento é
ignorado até que o dispositivo retorne para o estado de repouso.


T3 - Trabalho sobre sincronização de relógios e mensagens via sockets

Implementar uma aplicação distribuída que usa o modelo cliente-servidor, e onde a comunicação entre
os processos seja feita através de mensagens, usando UDP como nos exemplos em udpcliente2006.c e
udpservidor2006.c .
   
Duas trocas de mensagens são possíveis entre um processo cliente e um processo servidor:
M1) Cliente manda uma mensagem TESTE para o servidor, que imediatamente responde com uma
mensagem OK.
M2) Cliente manda uma mensagem LEHORA para o servidor, que imediatamente responde com a
hora local em sua máquina.
  
O cliente é capaz de sincronizar o seu relógio com o relógio do servidor, através de 3 trocas de mensagens:
  
Passo 1) Cliente faz um TESTE e mede o tempo para uma mensagem ir e voltar do servidor, desta
forma estima o atraso da rede. Como o atraso na rede é variável, fazer várias medições e obter a média.

Passo 2) Cliente faz um LEHORA e obtém a hora do servidor, acrescenta o atraso estimado para
a rede e acerta o seu relógio pelo relógio do servidor. Como alterar o relógio do computador é
uma operação restrita, criar uma função le_relógio_corrigido( ) no programa que implementa um
mecanismo de correção.

Passo 3) Cliente faz um TESTE e calcula o erro residual entre o seu relógio e o relógio do servidor,
após a sincronização do seu relógio e considerando o atraso na rede.

Realizar as seguintes experiências, envolvendo 3 computadores:

Experiência 1) Medir a diferença entre os relógios do computador A e de dois computadores B e C, sem fazer sincronização.

Experiência 2) Sincronizar os relógios dos clientes B e C com o servidor A e medir o erro residual.

Experiência 3) Medir o erro residual sucessivamente, em intervalos de 10 segundos.

Obs 3 - O relatório técnico Trabalhando com o Tempo Real em Aplicações Sobre o Linux pode
ser consultado sobre funções Unix para manipular tempo.
  

T4 - Trabalho sobre tabelas e pthreads

Implementar um programa concorrente que simula um sistema de transporte urbano
inteligente. Este programa será composto por dois arquivos ".c" separados. O trabalho
deve ser feito em C, no Linux, usando a biblioteca das pthreads.
      
Em um arquivo deve ser implementado a central de informações sobre ônibus, a qual
aceita 3 tipos de chamadas de funções:
  
void informa_posição( int número_do_ônibus, int linha, int parada);
  
Usada pelas várias threads tipo ônibus para informar sua atual posição dentro da
cidade, conforme o conceito de linha de ônibus e parada ao longo da linha.
  
double distância_próximo_ônibus( int linha, int parada);
  
Usada pelas várias threads tipo pessoa para indagar sobre a posição do ônibus  que
está mais próximo da parada em questão. O objetivo é fornecer para esta pessoa
uma indicação de quanto tempo vai demorar até o próximo ônibus chegar na parada
onde ela está esperando.
  
void espera_ônibus_chegar( int linha, int parada);
  
Usada pelas várias threads tipo pessoa para bloquear até o próximo ônibus da
linha indicada chegar na parada indicada. Usar uma variável condição para obter
este efeito.

As 3 rotinas descritas formam um monitor, juntamente com os dados sobre as
linhas de ônibus e a posição atual de cada ônibus. Usar variáveis tipo lock
para proteger o acesso às variáveis compartilhadas.
 
Implementar um segundo módulo (outro arquivo .c), onde são criadas várias threads
tipo ônibus e várias threads tipo pessoa. Cada uma dessas threads executa um laço
infinito, onde existe uma chamada sleep, seguida de uma chamada a alguma função
do monitor. Testar as várias condições possíveis que podem ocorrer nesta aplicação.
Observar que podem existir várias pessoas na mesma parada da mesma linha
de ônibus, assim como existem vários ônibus em cada linha.

Considerar:
 
- 3 linhas de ônibus;
- 7 paradas por linha;
- 2 ônibus por linha;
- 20 pessoas distribuídas pelas paradas e linhas.

T5 - Trabalho do controlador/supervisor completo

Implementar o controle do sistema descrito aqui,  assim como a supervisão de duas
unidades independentes de tal sistema.
 
Simulador é usado para simular uma unidade de caldeira e é chamado com:
      java -jar aquecedor2006_2.jar  <número-porta-escutada>

A caldeira possui instrumentação embutida e aceita os seguintes comandos:
"sta0"            lê valor de Ta
"st-0"            lê valor de T
"sti0"             lê valor de Ti
"sno0"           lê valor de No
"sh-0"           lê valor de H
"ani123.4"    define valor de Ni como 123.4
"aq-567.8"   define valor de Q como 567.8
 

Cuidado com a formatação dos valores em ponto flutuante.

Implementar dois programas em C no Linux, usando a biblioteca de pthreads.

O programa CONTROLADOR deve incluir as seguintes funcionalidades:

- Laço de controle como tarefa periódica para a temperatura;
- Laço de controle como tarefa periódica para o nível;
- Detecção de temperatura fora do intervalo de valores válidos;
- Informações na tela sobre a situação corrente;
- Recepção através da rede local dos valores de referência para temperatura e nível;
- Recepção através da rede local dos limites para o intervalo de valores de temperatura válidos;
- Envio através da rede local de mensagem de alarme para o supervisor quando o valor medido
da temperatura sai fora do intervalo de valores válidos definido.

O programa SUPERVISOR deve incluir as seguintes funcionalidades:

- Supervisão simultânea de DUAS caldeiras;
- Entrada através do teclado dos valores de referência para nível e temperatura, e envio
desses valores para o respectivo controlador através da rede local;
- Entrada através do teclado dos valores limites para o intervalo de temperaturas válidas,
e envio desses valores para os dois controladores através da rede local;
- Recepção através da rede local do alarme gerado pelo controlador quando a temperatura
sai do intervalo de temperaturas válidas;
- Solicitação periódica dos valores lidos de temperatura para cada um dos controladores e
armazenagem desses dados em arquivo no computador do SUPERVISOR.

Cada um dos dois programas deve ser composto por várias threads que colaboram entre si
através de variáveis compartilhadas.

Cada caldeira a ser controlada será simulada por um outro programa, o simulador, cujo código executável
é fornecido. A comunicação entre o CONTROLADOR e o simulador da sua respectiva caldeira será através
de sockets UDP/IP. Da mesma forma, a comunicação entre os dois CONTROLADORES e o SUPERVISOR
deve ser feita através de sockets UDP/IP. O protocolo entre CONTROLADOR e SUPERVISOR deve ser
definido como parte do trabalho.

    
Avaliação composta por:
    - Código fonte;
    - Texto explicando qual a função de cada thread, quais variáveis compartilhadas cada uma acessa e qual
o protocolo usado entre CONTROLADOR e SUPERVISOR;
    - Apresentação individual do trabalho.

Outros requisitos:
    - Usar mutex para proteger as variáveis compartilhadas;
    - Usar variáveis condição para liberar as threads de alarme;
    - Tarefas periódicas implementadas com precisão e não com sleep fixo (ver apostila na página da disciplina);
    - Período do controlador de temperatura deve ser 150ms;
    - Período do controlador de nível deve ser 200ms;
    - Atualização da tela pode ser com sleep simples de 1 segundo;
    - Usar buffer duplo para a gravação de dados em arquivos, feita por thread própria.

Alguns aspectos para a composição da nota do trabalho do controlador:
- Fez no Linux, em C, usando a biblioteca das pthreads ?
- Foi usado um mutex para cada estrutura compartilhada ?
- A aplicação possui alarme disparado via variável condição ?
- A aplicação apresenta valores dos sensores na tela ?
- A aplicação possui laços de controle para temperatura e nível ?
- A aplicação acessa teclado durante a execução do controlador, afeta valor de referência ?
- A aplicação grava leituras em arquivo utilizando buffer duplo e thread própria ?
- As tarefas de controle são realmente periódicas ?
- Existe algum warning na compilação ?
- Elegância do design da solução e legibilidade do código.