Dokumentation: Drehteller, Prüfer & Auswerfer

This commit is contained in:
Johannes Theiner 2020-12-07 11:49:32 +01:00
parent 19b9c1d7c6
commit cc2fd89e8f
Signed by: joethei
GPG Key ID: 9D2B9A00FDA85BCD
3 changed files with 139 additions and 85 deletions

View File

@ -30,7 +30,8 @@
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static RT_TASK turntable_task, drill_task, tester_task, output_task; static RT_TASK turntable_task, drill_task, tester_task, output_task;
static MBX turntable_status_mbx, tester_status_mbx, output_status_mbx, drill_status_mbx; static MBX turntable_status_mbx, tester_status_mbx;
static MBX output_status_mbx, drill_status_mbx;
static MBX output_data_mbx, drill_data_mbx, turntable_data_mbx; static MBX output_data_mbx, drill_data_mbx, turntable_data_mbx;
static SEM semaphore; static SEM semaphore;
@ -75,7 +76,8 @@ void end(bool fail) {
* @return status code(0: success, 1: failure) * @return status code(0: success, 1: failure)
*/ */
int readAll(int type, int *result) { int readAll(int type, int *result) {
int res = rt_modbus_get(connection, type, 0, (unsigned short *) result); int res = rt_modbus_get(connection, type, 0,
(unsigned short *) result);
return res; return res;
} }
@ -88,7 +90,8 @@ int readAll(int type, int *result) {
int readData(int part) { int readData(int part) {
int value = 0; int value = 0;
rt_sem_wait(&semaphore); rt_sem_wait(&semaphore);
//the semaphore needs to be locked before this code executes, so we can't adhere to the ISO standard here. //the semaphore needs to be locked before this code executes,
// so we can't adhere to the ISO standard here.
int code = readAll(DIGITAL_IN, &value); int code = readAll(DIGITAL_IN, &value);
int result = (part & value); int result = (part & value);
rt_sem_signal(&semaphore); rt_sem_signal(&semaphore);
@ -106,7 +109,8 @@ void disable(int actor) {
rt_sem_wait(&semaphore); rt_sem_wait(&semaphore);
if(readAll(DIGITAL_OUT, &value)) end(true); if(readAll(DIGITAL_OUT, &value)) end(true);
else { else {
int result = rt_modbus_set(connection, DIGITAL_OUT, 0, value &= ~actor); int result = rt_modbus_set(connection, DIGITAL_OUT, 0,
value &= ~actor);
rt_sem_signal(&semaphore); rt_sem_signal(&semaphore);
if (result) end(true); if (result) end(true);
} }
@ -122,7 +126,8 @@ void enable(int actor) {
rt_sem_wait(&semaphore); rt_sem_wait(&semaphore);
if (readAll(DIGITAL_OUT, &output)) end(true); if (readAll(DIGITAL_OUT, &output)) end(true);
else { else {
int result = rt_modbus_set(connection, DIGITAL_OUT, 0, output |= actor); int result = rt_modbus_set(connection, DIGITAL_OUT, 0,
output |= actor);
rt_sem_signal(&semaphore); rt_sem_signal(&semaphore);
if(result) end(true); if(result) end(true);
} }
@ -211,7 +216,8 @@ static void turntable(long data) {
//always read from mailbox to make sure that no overflow occurs. //always read from mailbox to make sure that no overflow occurs.
int msg1 = receiveMailNonBlocking(&turntable_data_mbx); int msg1 = receiveMailNonBlocking(&turntable_data_mbx);
int msg2 = receiveMailNonBlocking(&turntable_data_mbx); int msg2 = receiveMailNonBlocking(&turntable_data_mbx);
if(readData(SENSOR_PART_TURNTABLE) || msg1 || msg2) {//if a part is on any of the sensors //if a part is on any of the sensors
if(readData(SENSOR_PART_TURNTABLE) || msg1 || msg2) {
enable(ACTOR_TURNTABLE); enable(ACTOR_TURNTABLE);
sleepMs(100); sleepMs(100);
if (!readData(SENSOR_TURNTABLE_POS)) { if (!readData(SENSOR_TURNTABLE_POS)) {
@ -242,10 +248,12 @@ static void tester(long data) {
while (1) { while (1) {
receiveMail(&tester_status_mbx); receiveMail(&tester_status_mbx);
if(readData(SENSOR_PART_TESTER)) { if(readData(SENSOR_PART_TESTER)) {
sendMailNonBlocking(&turntable_data_mbx, 1);//turntable should turn on the next turn. //turntable should turn on the next turn.
sendMailNonBlocking(&turntable_data_mbx, 1);
enable(ACTOR_TESTER); enable(ACTOR_TESTER);
sleepMs(500); sleepMs(500);
if(readData(SENSOR_PART_TEST)) {//should the drill be active on the next turn ? //should the drill be active on the next turn ?
if(readData(SENSOR_PART_TEST)) {
sendMailNonBlocking(&drill_data_mbx, 1); sendMailNonBlocking(&drill_data_mbx, 1);
}else { }else {
sendMailNonBlocking(&drill_data_mbx, 0); sendMailNonBlocking(&drill_data_mbx, 0);
@ -277,9 +285,12 @@ static void drill(long data) {
//start processing //start processing
while (1) { while (1) {
receiveMail(&drill_status_mbx); receiveMail(&drill_status_mbx);
if(readData(SENSOR_PART_DRILL)) {//if part is in drill //if part is in drill
sendMailNonBlocking(&turntable_data_mbx, 1);//turntable should be active on the next turn. if(readData(SENSOR_PART_DRILL)) {
if(receiveMailNonBlocking(&drill_data_mbx)) {//read test result from mailbox //turntable should be active on the next turn.
sendMailNonBlocking(&turntable_data_mbx, 1);
//read test result from mailbox.
if(receiveMailNonBlocking(&drill_data_mbx)) {
enable(ACTOR_PART_HOLD); enable(ACTOR_PART_HOLD);
enable(ACTOR_DRILL); enable(ACTOR_DRILL);
enable(ACTOR_DRILL_DOWN); enable(ACTOR_DRILL_DOWN);
@ -300,7 +311,8 @@ static void drill(long data) {
disable(ACTOR_DRILL_UP); disable(ACTOR_DRILL_UP);
disable(ACTOR_PART_HOLD); disable(ACTOR_PART_HOLD);
} }
sendMailNonBlocking(&output_data_mbx, 1);//should the output be active on the next turn ? //should the output be active on the next turn ?
sendMailNonBlocking(&output_data_mbx, 1);
} }
sendMail(&turntable_status_mbx, 1); sendMail(&turntable_status_mbx, 1);
} }
@ -317,7 +329,8 @@ static void output(long data) {
//start processing //start processing
while (1) { while (1) {
receiveMail(&output_status_mbx); receiveMail(&output_status_mbx);
if(receiveMailNonBlocking(&output_data_mbx)) {//should the output be activated //should the output be activated
if(receiveMailNonBlocking(&output_data_mbx)) {
enable(ACTOR_EXIT); enable(ACTOR_EXIT);
sleepMs(500); sleepMs(500);
disable(ACTOR_EXIT); disable(ACTOR_EXIT);

View File

@ -1,9 +1,8 @@
%Copyright: 2020, Johannes Theiner <kontakt@joethei.de> %Copyright: 2020, Johannes Theiner <kontakt@joethei.de>
\ProvidesPackage{hs-el-text} \ProvidesPackage{hs-el-text}
\RequirePackage{graphicx}
\RequirePackage[ngerman]{babel} \RequirePackage[ngerman]{babel}
\RequirePackage[iso]{isodate} \RequirePackage{graphicx}
\RequirePackage{amsmath} \RequirePackage{amsmath}
\RequirePackage{amssymb} \RequirePackage{amssymb}
\RequirePackage{amstext} \RequirePackage{amstext}
@ -38,14 +37,17 @@ anchorcolor = black]{hyperref}
\RequirePackage{makecell} \RequirePackage{makecell}
\RequirePackage{plantuml} \RequirePackage{plantuml}
\RequirePackage{fontspec} \RequirePackage{fontspec}
\RequirePackage{wrapfig}
\RequirePackage{lipsum}
\RequirePackage{subfig}
\usetikzlibrary{positioning, shapes.geometric} \usetikzlibrary{positioning, shapes.geometric}
\RequirePackage[final]{draftwatermark} \RequirePackage[]{draftwatermark}
%watermark %watermark
\SetWatermarkText{Preview} \SetWatermarkText{Preview}
\SetWatermarkColor{gray} \SetWatermarkColor{red}
\SetWatermarkFontSize{35.83pt} \SetWatermarkFontSize{35.83pt}
\titlespacing\section{0pt}{12pt}{10pt} \titlespacing\section{0pt}{12pt}{10pt}
@ -101,7 +103,6 @@ autogobble
\ofoot{Seite \thepage \hspace{1pt} von \pageref{LastPage}} \ofoot{Seite \thepage \hspace{1pt} von \pageref{LastPage}}
\makeindex \makeindex
\isodate
\renewcommand*{\maketitle}{% \renewcommand*{\maketitle}{%

174
index.tex
View File

@ -1,7 +1,5 @@
\documentclass[german, a4paper, headheight=36pt, parskip=true]{scrartcl} \documentclass[german, a4paper, headheight=36pt, parskip=true]{scrartcl}
\usepackage{hs-el-text} \usepackage{hs-el-text}
\usepackage{wrapfig}
\usepackage{lipsum}
\modul{Echtzeitdatenverarbeitung} \modul{Echtzeitdatenverarbeitung}
\semester{Wintersemester 2020/21} \semester{Wintersemester 2020/21}
@ -16,15 +14,22 @@
\section{Tasks}\label{sec:tasks} \section{Tasks}\label{sec:tasks}
\subsection{Drehteller}\label{subsec:task_turntable} \begin{figure}[H]
\begin{wrapfigure}{L}{0.5\textwidth}
\centering \centering
\begin{plantuml} \begin{minipage}{.5\textwidth}
\centering
\begin{plantuml}
@startuml @startuml
scale 150 width scale 150 width
!include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu !include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu
start start
:Drehteller ausschalten; :Drehteller ausschalten;
:Auswefer Eingang ausschalten;
repeat
:Drehteller kurz anschalten;
:Auswerfer kurz betätigen;
repeat while(5 Durchläufe ?)
repeat repeat
:Prüfer fertig?< :Prüfer fertig?<
:Bohrer fertig?< :Bohrer fertig?<
@ -41,24 +46,23 @@
repeatwhile() repeatwhile()
kill kill
@enduml @enduml
\end{plantuml} \end{plantuml}
\caption{SDL Diagramm Drehteller} \captionof{figure}{SDL Diagramm Drehteller}
\label{fig:sdl-turntable} \label{fig:sdl-turntable}
\end{wrapfigure} \end{minipage}%
\begin{minipage}{.5\textwidth}
\lipsum[1-2] \centering
\begin{plantuml}
\subsection{Prüfer}\label{subsec:task_tester}
\begin{wrapfigure}{R}{0.5\textwidth}
\begin{plantuml}
@startuml @startuml
!include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu !include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu
start
:Prüfer einfahren; :Prüfer einfahren;
:Prüfer fertig>
repeat repeat
:Drehteller fertig?< :Drehteller fertig?<
if(Werkstück vorhanden ?) then (ja) if(Werkstück vorhanden ?) then (ja)
:Prüfer ausfahren; :Prüfer ausfahren;
if(Werkstück Normallage ?) then (ja) if(Werkstück in Normallage ?) then (ja)
:Sende Bohrer(an)> :Sende Bohrer(an)>
else (nein) else (nein)
:Sende Bohrer(aus)> :Sende Bohrer(aus)>
@ -70,72 +74,108 @@
repeatwhile() repeatwhile()
kill kill
@enduml @enduml
\end{plantuml} \end{plantuml}
\caption{SDL Diagramm Prüfer} \captionof{figure}{SDL Diagramm Prüfer}
\label{fig:sdl-tester} \label{fig:sdl-tester}
\end{wrapfigure} \end{minipage}
\end{figure}
\lipsum[2-4] \begin{figure}[H]
\centering
\subsection{Bohrer}\label{subsec:task_drill} \begin{minipage}{.5\textwidth}
\begin{wrapfigure}{L}{0.5\textwidth} \centering
\begin{plantuml} \begin{plantuml}
@startuml @startuml
scale 150 width scale 150 width
!include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu !include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu
:Bohrer ausschalten; start
:Bohrer hochfahren;
:Werkstück loslassen;
repeat
:Drehteller fertig?<
if(Werkstück vorhanden?) then(ja)
:Empfange Lage des Werkstücks<
:Sende Auswerfer>
if(Teil in Normallage?) then(ja)
:Werkstück festhalten;
:Bohrer anschalten;
:Bohrer herunterfahren;
:Warte bis Bohrer unten;
:Bohrer hochfahren;
:Warte bis Bohrer oben;
:Bohrer ausschalten; :Bohrer ausschalten;
:Bohrer hochfahren;
:Werkstück loslassen; :Werkstück loslassen;
else(nein) :Bohrer fertig>
endif repeat
else (nein) :Drehteller fertig?<
endif if(Werkstück vorhanden?) then(ja)
:Bohrer fertig> :Empfange Lage des Werkstücks<
repeatwhile() :Sende Auswerfer>
kill if(Teil in Normallage?) then(ja)
@enduml :Werkstück festhalten;
\end{plantuml} :Bohrer anschalten;
\caption{SDL Diagramm Bohrer} :Bohrer herunterfahren;
\label{fig:sdl-drill} :Warte bis Bohrer unten;
\end{wrapfigure} :Bohrer hochfahren;
:Warte bis Bohrer oben;
\lipsum[2-4] :Bohrer ausschalten;
:Werkstück loslassen;
\subsection{Auswerfer}\label{subsec:output} else(nein)
\begin{wrapfigure}{R}{0.5\textwidth} endif
\begin{plantuml} else (nein)
endif
:Bohrer fertig>
repeatwhile()
kill
@enduml
\end{plantuml}
\captionof{figure}{SDL Diagramm Bohrer}
\label{fig:sdl-drill}
\end{minipage}%
\begin{minipage}{.5\textwidth}
\centering
\begin{plantuml}
scale 250 width scale 250 width
@startuml @startuml
!include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu !include https://raw.githubusercontent.com/bharatrajagopalan/plantuml-styles/master/activity_skin.pu
start
:Auswerfer einfahren; :Auswerfer einfahren;
:Auswerfer fertig>
repeat repeat
:Drehteller fertig?< :Drehteller fertig?<
:Auswerfer< :Auswerfer<
:Auswerfen; if(Auswerfen ?) then (ja)
:Auswerfer betätigen;
endif
:Auswerfer fertig> :Auswerfer fertig>
repeatwhile() repeatwhile()
kill kill
@enduml @enduml
\end{plantuml} \end{plantuml}
\caption{SDL Diagramm Auswerfer} \captionof{figure}{SDL Diagramm Auswerfer}
\label{fig:sdl-output} \label{fig:sdl-output}
\end{wrapfigure} \end{minipage}
\end{figure}
\lipsum[2-4] Um einen konsistenten Startpunkt zu erhalten werden bei allen Tasks zu Beginn sämtliche vom entsprechenden
Task verwendeten Aktoren auf Ausgangsposition zurückgesetzt.
\subsection{Drehteller}\label{subsec:task_turntable}
Nach dem Zurücksetzen vom Drehteller und des Auswerfers am Eingang fährt der Drehteller zuerst fünf Runden,
bei denen der Auswerfer am Ausgang bedingungslos betätigt wird,
um Teile die sich vielleicht noch in der Anlage befinden aus dieser zu entfernen.
Um eine Synchronisierung zu erlangen wird der Drehteller erst aktiv, wenn Prüfer, Bohrer und Auswerfer
mit einer Nachricht auf die Status Mailbox signalisiert haben das sie mit ihren Aktionen fertig sind.
Liegt auf mindestens einem Sensor(Eingang, Tester oder Bohrer) ein Teil wird der Drehteller
aktiviert und erst wieder deaktiviert, wenn dieser wieder in Position ist.
Nun wird den anderen Tasks über Nachrichten signalisiert das diese aktiv werden können
und der Prozess beginnt erneut.
\subsection{Prüfer}\label{subsec:task_tester}
Sobald der Prüfer aktiv werden darf(Nachricht auf Status Mailbox) wird überprüft ob
ein Teil auf dem Sensor liegt.
Liegt ein Teil auf dem Sensor fährt der Prüfer aus und das Testergebnis wird dem
Bohrer über eine Nachricht mitgeteilt.
Nun wird der Prüfer wieder eingefahren und der Drehteller kann wieder aktiv werden.
Der Prozess beginnt nun wieder von vorne.
\subsection{Bohrer}\label{subsec:task_drill}
\lipsum[2-3]
\subsection{Auswerfer}\label{subsec:output}
Da für den Auswerfer keine Sensoren existieren sendet der Bohrer den Status seines Sensors per Nachricht
an den Auswerfer, der auf Basis dieser auslöst.
\section{Hilfsfunktionen}\label{sec:functions} \section{Hilfsfunktionen}\label{sec:functions}
\lipsum[2-4] \lipsum[2-4]