DAS5306: Informática Industrial II

Trabalhos para 2005/1

Trabalhos entregues após a data estipulada perdem 1 ponto por dia de
atraso, inclusive sábado e domingo.

Trabalhos entreguem no dia correto mas depois do horário de
aula perdem 1 ponto.

Apresentações individuais podem ser solicitadas.

Trabalho sobre tabelas

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 ingresso;
};

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 matrícula 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.
 

Trabalho sobre algoritmo de escalonamento

O trabalho consiste em implementar um dos módulos descritos abaixo.
A implementação deve ser feita com a linguagem de programação C, no Linux.

São propostos vários módulos diferentes. Cada grupo deve escolher um
módulo e comunicar sua escolha ao professor. A comunicação deve conter,
por escrito, o nome dos integrantes do grupo e o número do módulo escolhido.

Turma [A] pega módulos com número impar.
Turma [B] pega módulos com número par.

Cada grupo deverá implementar um módulo diferente. No caso de dois ou mais
grupos escolherem o mesmo módulo, somente o grupo que manifestou seu interesse
primeiro poderá implementar o módulo. Os demais deverão escolher outro módulo.

O módulo escolhido deverá ser testado através da função main, com chamadas
para as seguintes funções:

void insere_na_fila( struct descritor_de_processo *dp);
void avança_relógio( void);

A estrutura descritor_de_processo deve ser definida conforme as necessidades
de cada algoritmo.

A entrega inclui:
(a) Listagem do código fonte;
(b) Demonstração no computador, com a presença dos membros do grupo.

O algoritmo a ser utilizado para o escalonador é:

1 - Filas multinível utilizando prioridade preemptiva (fila de maior prioridade) e FCFS (fila de menor prioridade) dentro das filas e prioridade preemptiva entre filas.
2 - Filas multinível utilizando prioridade preemptiva (fila de maior prioridade) e FCFS (fila de menor prioridade) dentro das filas e round-robin entre filas (70% e
30% do tempo da cpu).
3 - Filas multinível utilizando prioridade não preemptiva dentro das duas filas e e round-robin entre filas (70% e 30% do tempo da cpu).
4 - Filas multinível utilizando round-robin (fila de maior prioridade) e FCFS (fila de menor prioridade) dentro das filas e prioridade não preemptiva entre filas.
5 - Filas multinível utilizando round-robin dentro das filas e round-robin entre filas (70% e 30% do tempo da cpu).
6 - Filas multinível utilizando round-robin dentro das filas e prioridade preemptiva entre filas.
7 - Filas multinível utilizando round-robin (fila de maior prioridade) e FCFS (fila de menor prioridade) dentro das filas e prioridade preemptiva entre filas.
8 - Filas multinível utilizando prioridade preemptiva (fila de maior prioridade) e FCFS (fila de menor prioridade) dentro das filas e prioridade não preemptiva entre
filas.
9 - Filas multinível utilizando round-robin dentro das filas e prioridade não preemptiva entre filas.
10 - Filas multinível utilizando round-robin (primeira fila) e FCFS (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do tempo da cpu).
11 - Filas multinível utilizando prioridade não preemptiva (primeira fila) e FCFS (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do tempo da
cpu).
12 - Filas multinível utilizando prioridade não preemptiva (primeira fila) e round-robin (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do tempo
da cpu).
13 - Filas multinível utilizando prioridade não preemptiva (fila de maior prioridade) e round-robin (fila de menor prioridade) dentro das filas e prioridade preemptiva
entre filas.
14 - Filas multinível utilizando prioridade não preemptiva (fila de maior prioridade) e round-robin (fila de menor prioridade) dentro das filas e prioridade não
preemptiva entre filas.
15 - Filas multinível utilizando prioridade preemptiva (primeira fila) e round-robin (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do tempo da
cpu).
16 - Filas multinível utilizando prioridade preemptiva (fila de maior prioridade) e round-robin (fila de menor prioridade) dentro das filas e prioridade preemptiva
entre filas.
17 - Filas multinível utilizando prioridade preemptiva (fila de maior prioridade) e round-robin (fila de menor prioridade) dentro das filas e prioridade não preemptiva
entre filas.
18 - Filas multinível utilizando prioridade preemptiva (primeira fila) e prioridade preemptiva (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do
tempo da cpu).
19 - Filas multinível utilizando prioridade preemptiva (primeira fila) e prioridade não preemptiva (segunda fila) dentro das filas e round-robin entre filas (70% e 30%
do tempo da cpu).
20 - Filas multinível utilizando prioridade não preemptiva (primeira fila) e prioridade preemptiva (segunda fila) dentro das filas e round-robin entre filas (70% e 30%
do tempo da cpu).
21 - Filas multinível utilizando round-robin (fila de maior prioridade) e prioridade preemptiva (fila de menor prioridade) dentro das filas e prioridade não preemptiva
entre filas.
22 - Filas multinível utilizando round-robin (fila de maior prioridade) e prioridade preemptiva (fila de menor prioridade) dentro das filas e prioridade preemptiva
entre filas.
23 - Filas multinível utilizando round-robin (fila de maior prioridade) e prioridade não preemptiva (fila de menor prioridade) dentro das filas e prioridade não
preemptiva entre filas.
24 - Filas multinível utilizando round-robin (primeira fila) e prioridade preemptiva (segunda fila) dentro das filas e round-robin entre filas (70% e 30% do tempo da
cpu).
 

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:

controlador.c    Exemplo do programa controlador a ser feito

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

envasilhamento.c    Simulador da planta já compilado

teste    Exemplo executável do controlador

Escrever um novo controlador.c que seja automático (o fornecido é manual)
e que maximize a produtividade da planta.

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.
 
 

Trabalho das tarefas periódicas

Implementar um laço periódico seguindo as recomendações do relatório técnico
"Trabalhando com o Tempo Real em Aplicações Sobre o Linux" e o
exemplo  exemplo-periodica.c .

Medir o jitter de saída, isto é, a diferença entre o período da tarefa e o tempo entre duas
conclusões sucessivas da tarefa. Compensar no sleep seguinte, alterando o valor do sleep
conforme o erro observado na ativação anterior. A compensação pode ser no estilo
de um controlador PI.

Apresentar histogramas para o:

- Tempo entre o início do período e o início da tarefa;

- Tempo entre duas conclusões consecutivas da tarefa.

Plotar o histograma usando matlab, excel, qualquer planilha eletrônica, ou mesmo
a mão.

Trabalho das pthreads

Implementar um programa usando a biblioteca das pthreads no Linux, em C, onde existem
3 threads. Duas threads são periódicas, com períodos de 100 ms e 500 ms. A cada período,
elas obtem a hora de início e escrevem este valor em um buffer. A outra thread espera até
o buffer ficar cheio, grava este buffer em um arquivo, e volta a esperar.
 
Deve ser usado um esquema de buffer duplo. As threads escrevem no buffer A e quando
ele fica cheio acordam a thread que escreve em disco e passam a usar o buffer B. Quando
o buffer B estiver cheio a thread de escrita em disco é novamente acordada e as threads
periódicas passam a usar o buffer A novamente.
 
Programar a solução na forma de um monitor com duas funções de acesso:
escreve_hora_no_buffer() chamada pelas threads periódicas
espera_buffer_ficar_cheio() chamada pela thread que escreve no arquivo
 

Trabalho de mensagens via sockets

 Alterar o trabalho do controlador da planta de envasilhamento para que:

- O simulador da planta seja um programa separado (servidor);
- O controlador da planta seja um programa separado (cliente);
- A comunicação entre eles seja através de mensagens, usando UDP como mostrado.

Será necessário criar um protocolo para a interface do servidor. Por exemplo,
o comando "acionaEsteira" pode ser o envio da letra "E" do cliente/controlador
para o servidor/simulador. Cada função da interface do simulador deverá
ser uma mensagem diferente.

É PROIBIDO alterar os arquivos do simulador:

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

envasilhamento.c   Simulador da planta já compilado
      
Criar um arquivo com o nome servidor.c que, compilado junto com
o envasilhamento.c inalterado, ofereça os seviços via rede.
           

Trabalho do controlador completo

Implementar o controle do sistema descrito aqui.
 
Simulador é chamado com:
      java -jar aquecedor2004_2.jar
escuta a porta 4545.

Aceita os 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 um programa em C no Linux usando a biblioteca de pthreads que inclua
as seguintes funcionalidades:

- Laço de controle com tarefa periódica;
- Alarme associado com valores das variáveis amostradas;
- Armazenagem em arquivo de leitura periódicas;
- Informações periódicas na tela;
- Leitura de comandos e/ou valores a partir do teclado.

O programa em si deve ficar no arquivo "controle.c" e deve ser composto por várias threads
que colaboram entre si através de variáveis compartilhadas.

A planta será simulada por um outro programa, cujo código executável será
fornecido. A comunicação entre o controle e o simulador será através
de sockets UDP/IP.

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

Outros requisitos:
    - Cada variável compartilhada deve ter seu próprio mutex.
    - Variáveis condição devem ser usadas para liberar as threads de alarme.
    - Tarefas periódicas implementadas com precisão e não com sleep fixo.

Alguns aspectos para a composição da nota do trabalho do controlador:
- Fez no Linux, em C, usando a biblioteca das pthreads ?
- A aplicação apresenta valores na tela ?
- A aplicação grava leituras em arquivo ?
- A aplicação acessa teclado durante a execução do controlador ?
- A aplicação possui alarme disparado via variável condição ?
- A aplicação possui laço de controle ?
- Foi usado um mutex para cada estrutura compartilhada ?
- As tarefas são realmente periódicas, como feito em aula ?
- Elegância do design da solução.
- Legibilidade do código.