diff --git a/doc/fact-sheet/Makefile b/doc/fact-sheet/Makefile new file mode 100644 index 0000000..6f6aa59 --- /dev/null +++ b/doc/fact-sheet/Makefile @@ -0,0 +1,124 @@ +# Makefile for LaTeX documents +# +# Intended for use in Linux and Git Bash +# TeXstudio (MiKTeX) compatibility through TeX directives +# +# by Dominik Mueller (@MuellerDominik) +# +# Targets: +# +# all Build document if necessary +# build Always (re)build document +# pdflatex Run pdfLaTeX +# debug Run pdfLaTeX in verbose mode +# bibliography, bib Run biber +# glossary, makeglossaries Run makeglossaries +# snapshot Create snapshot +# remove-snapshots Remove all snapshots +# directives Add proper TeX directives +# remove-directives Remove all TeX directives +# clean Remove auxiliary files +# purge Remove all generated files + +# Document name +DOCUMENT = fact-sheet +OUTPUT = p5_aionfpga_fact-sheet_canzani_mueller + +# Directories and auxiliary files +TEMP_DIR = temp +BUILD_DIR = build +SECTIONS_DIR = sections +SNAPSHOTS_DIR = snapshots +PDF_FILE = $(BUILD_DIR)/$(OUTPUT).pdf +BIB_FILE = $(BUILD_DIR)/$(OUTPUT).bcf +GLOSS_FILE = $(BUILD_DIR)/$(OUTPUT).glo + +# Source files (omit whitespaces) and timestamp +TEX_FILES := $(shell find . -name "*.tex") +TIMESTAMP := $(shell date +%Y-%m-%d_%H-%M-%S) + +# Document ID (sliced for TeX directive 'document-id') +DOC_ID := $(shell echo -n $(TIMESTAMP) | sha256sum | cut -c1-32) +DOC_ID1 := $(shell echo -n $(DOC_ID) | cut -c1-8) +DOC_ID2 := $(shell echo -n $(DOC_ID) | cut -c9-12) +DOC_ID3 := $(shell echo -n $(DOC_ID) | cut -c13-16) +DOC_ID4 := $(shell echo -n $(DOC_ID) | cut -c17-20) +DOC_ID5 := $(shell echo -n $(DOC_ID) | cut -c21-32) + +# Commands (with their respective arguments) +PDFLATEX_ARGS = -output-directory=$(BUILD_DIR) -jobname=$(OUTPUT) $(DOCUMENT) +PDFLATEX = pdflatex -interaction=batchmode $(PDFLATEX_ARGS) > /dev/null 2>&1 +PDFLATEX_DEBUG = pdflatex -interaction=nonstopmode -halt-on-error $(PDFLATEX_ARGS) +BIBLIOGRAPHY = biber --onlylog --output-directory $(BUILD_DIR) $(OUTPUT) +GLOSSARY = makeglossaries -q -d $(BUILD_DIR) $(OUTPUT) + +# TeX directives for TeXstudio with MiKTeX on Windows (Perl installed) +DIR_ID = % !TeX document-id = {$(DOC_ID1)-$(DOC_ID2)-$(DOC_ID3)-$(DOC_ID4)-$(DOC_ID5)} +DIR_COMPILE = % !TeX TXS-program:compile = pdflatex -synctex=1 -interaction=nonstopmode $(PDFLATEX_ARGS).tex +DIR_BIB = % !TeX TXS-program:bibliography = biber --output-directory $(BUILD_DIR) $(OUTPUT) +DIR_GLOSS = % !TeX TXS-program:glossary = makeglossaries -d $(BUILD_DIR) $(OUTPUT) +DIR_VIEW = % !TeX TXS-program:view = txs:///view-pdf ./$(BUILD_DIR)/$(OUTPUT).pdf +DIRECTIVES = $(DIR_ID)\n$(DIR_COMPILE)\n$(DIR_BIB)\n$(DIR_GLOSS)\n$(DIR_VIEW)\n\n + +# Rebuilds document if source files (*.tex only) have been changed +.PHONY: all +all: $(PDF_FILE) + +.PHONY: build +build $(PDF_FILE): $(TEX_FILES) + @mkdir -p $(BUILD_DIR)/$(SECTIONS_DIR)/ + @$(PDFLATEX) + @$(BIBLIOGRAPHY) + @$(GLOSSARY) + @$(PDFLATEX) + @$(PDFLATEX) + +.PHONY: pdflatex +pdflatex $(BIB_FILE) $(GLOSS_FILE): + @$(PDFLATEX) + +.PHONY: debug +debug: + @$(PDFLATEX_DEBUG) + +.PHONY: bibliography bib +bibliography bib: $(BIB_FILE) + @$(BIBLIOGRAPHY) + +.PHONY: glossary makeglossaries +glossary makeglossaries: $(GLOSS_FILE) + @$(GLOSSARY) + +.PHONY: snapshot +snapshot: + @mkdir -p $(SNAPSHOTS_DIR)/ + @cp -f $(PDF_FILE) $(SNAPSHOTS_DIR)/$(OUTPUT)_$(TIMESTAMP).pdf + +.PHONY: remove-snapshots +remove-snapshots: + @rm -rf $(SNAPSHOTS_DIR)/ + +# Removes all TeX directives and prepends the ones specified in this Makefile +.PHONY: directives +directives: + @sed -i '/^% !TeX/d' $(DOCUMENT).tex + @sed -i '/./,$$!d' $(DOCUMENT).tex + @sed -i '1s;^;$(DIRECTIVES);' $(DOCUMENT).tex + +# Removes all TeX directives and leading blank lines +.PHONY: remove-directives +remove-directives: + @sed -i '/^% !TeX/d' $(DOCUMENT).tex + @sed -i '/./,$$!d' $(DOCUMENT).tex + +.PHONY: clean +clean: + @mkdir -p $(TEMP_DIR)/ + @cp -f $(PDF_FILE) $(TEMP_DIR)/$(OUTPUT).pdf > /dev/null 2>&1 || : + @rm -rf $(BUILD_DIR)/* > /dev/null 2>&1 || : + @cp -f $(TEMP_DIR)/$(OUTPUT).pdf $(PDF_FILE) > /dev/null 2>&1 || : + @rm -rf $(TEMP_DIR)/ + +.PHONY: purge +purge: + @rm -rf $(BUILD_DIR)/ $(TEMP_DIR)/ diff --git a/doc/fact-sheet/content.tex b/doc/fact-sheet/content.tex new file mode 100644 index 0000000..7bb0611 --- /dev/null +++ b/doc/fact-sheet/content.tex @@ -0,0 +1,102 @@ +\title{AI High-Performance Solution on FPGA} + +\team{Nico Canzani, Dominik M\"uller} + +% \client{FHNW Institute for Sensors and Electronics} +\client{Inst. for Sensors and Electronics} +% \client{FHNW / ISE} + +\coaches{% + Prof. Michael Pichler,\\ + Prof. Dr. Hanspeter Schmid +} + +\repo{https://git.io/p5-aionfpga} +% curl -i https://git.io -F "url=https://github.com/MuellerDominik/P5-AIonFPGA/" -F "code=p5-aionfpga" + +\fssummary{ + In a world of self-driving cars and automated quality control in manufacturing, real-time image classification is becoming increasingly important. + % Artificial intelligence, and deep learning in particular, are achieving excellent classification accuracies, but there are some challenges. + Artificial intelligence (AI), and deep learning in particular, are achieving excellent classification accuracies. + % However, a large labeled dataset of training data is required to train deep convolutional neural networks. + % However, a large labeled dataset of training data is required to train a convolutional neural networks (CNN). + However, the training of a convolutional neural network (CNN) requires a sufficiently large labeled dataset. + % However, the training of a deep convolutional neural network (CNN) required a sufficiently large labeled dataset. +} + +\fsgraphics{ + \begin{minipage}[t]{0.5\textwidth} + \begin{minipage}[t]{0.98\textwidth} + \includegraphics[width=\textwidth]{graphics/1574952009_278_10_stuffed-bunny.png} + \graphicscaption{Image of the \textit{Stuffed Bunny}} % Example / Sample + \end{minipage} + \end{minipage}% + \begin{minipage}[t]{0.5\textwidth} + \begin{flushright} + \begin{minipage}[t]{0.98\textwidth} + \includegraphics[width=\textwidth]{graphics/1574943825_125_8_hand-featherball.png} + \graphicscaption{Image of the \textit{Hand Featherball}} % Example / Sample + \end{minipage} + \end{flushright} + \end{minipage} +} + +\fscontent{ + % \section{Problem Statement} + \section{Difficulty} + Collecting a sufficiently large dataset of pictures is not trivial. + When done manually, the camera has to be started and stopped for each throw. + This likely creates many empty frames at the beginning and at the end of the capture. + Those empty and therefore invalid frames must be removed to avoid errors during the training of the CNN later on. + Furthermore, each valid frame must be labeled. + This procedure is very error-prone if it is performed manually for each individual frame. + + \newcol + \section{Software} + % To reliably detect a throw, a simple image change detection algorithm is implemented. + % It requires a repeated difference computation and therefore a circular buffer is used. + % To simplify this task, a camera throw detection mechanism is implemented and various Python scripts are used. + To simplify the image collection, a camera throw detection mechanism is implemented and various Python scripts are used. + The goal of the throw detection is to extract valid frames of a throw --- with objects on them --- from the continuous data stream of the camera. + Therefore, the throw detection needs to work in real time. + % At a frame rate of \SI{200}{fps}, there is $<\SI{5}{ms}$ to process a single frame (without the use of parallel computing). + At a frame rate of \SI{200}{fps}, there is less than \SI{5}{ms} to process a single frame. + % Due to this time constraint, a simple image change detection algorithm is employed. + Due to this time constraint, a simple image change detection algorithm is implemented. + + \newcol + % \section{Labeled Dataset} + \section{Dataset} + % The dataset contains images of 22 different throwing objects. + The dataset contains images of 22 different throwing objects, ranging from sports equipment to toys. + It is fully labeled and consists of more than \num{15000} usable images with at least 480 images of each object. + % All images were collected over the course of two days. + % The employed software allowed to collected all images over the course of two days. + The employed software made it possible to collect all images over the course of only two days. + % The above images show an example image of the \textit{Stuffed Bunny} and of the \textit{Hand Featherball}. + The above images are two examples from the labeled dataset. + The first one shows the \textit{Stuffed Bunny} and the second one shows the \textit{Hand Featherball}. +} + +\infobox{Throwing Booth}{ + % \begin{minipage}[t][][b]{0.45\textwidth} + % \includegraphics[height=50mm]{graphics/top_assembly.png} + % \end{minipage}\hfill% + \begin{minipage}{0.65\textwidth} + The throwing booth is constructed from general-purpose aluminium profiles. + % The rear panel is made of a white ABS plastic sheet for its robust impact strength and has a target hole. % features a target hole + Due to its robust impact strength, the rear panel is made of a white ABS plastic sheet and has a target hole. + % The side panel is made of a foamed PVC sheet to reduce light reflections. + The white side panel serves as a consistent background for the images. + It is made of a foamed PVC sheet with a fine-textured surface to reduce light reflections. + % The image acquisition system consists of a Baumer industrial camera and a suitable lens. + The image acquisition system consists of a Baumer industrial camera combined with a suitable lens. % imaging environment + % Strong diffuse lighting is used to minimize the required exposure time and to evenly illuminate the side panel. + Strong diffuse lighting is used to minimize the required exposure time and to illuminate the side panel as evenly as possible. + % A monitor is used to display the detected object. % display the result + Finally, a monitor is used to display the detected object. + \end{minipage}\hfill% + \begin{minipage}{0.32\textwidth} + \includegraphics[width=\textwidth]{graphics/top_assembly.png} + \end{minipage} +} diff --git a/doc/fact-sheet/fact-sheet.tex b/doc/fact-sheet/fact-sheet.tex new file mode 100644 index 0000000..ccac628 --- /dev/null +++ b/doc/fact-sheet/fact-sheet.tex @@ -0,0 +1,13 @@ +% !TeX document-id = {f144be9f-d20a-6673-972c-41c90886e461} +% !TeX TXS-program:compile = pdflatex -synctex=1 -interaction=nonstopmode -output-directory=build -jobname=p5_aionfpga_fact-sheet_canzani_mueller fact-sheet.tex +% !TeX TXS-program:bibliography = biber --output-directory build p5_aionfpga_fact-sheet_canzani_mueller +% !TeX TXS-program:glossary = makeglossaries -d build p5_aionfpga_fact-sheet_canzani_mueller +% !TeX TXS-program:view = txs:///view-pdf ./build/p5_aionfpga_fact-sheet_canzani_mueller.pdf + +\documentclass[english]{fhnwfactsheet} +% \usepackage{tikz} +% \usepackage{lipsum} + +\begin{document} + \includefactsheet{content.tex} +\end{document} diff --git a/doc/fact-sheet/fhnwfactsheet.cls b/doc/fact-sheet/fhnwfactsheet.cls new file mode 100644 index 0000000..8dd182f --- /dev/null +++ b/doc/fact-sheet/fhnwfactsheet.cls @@ -0,0 +1,391 @@ +%% +%% This is file `fhnwfactsheet.cls', +%% generated with the docstrip utility +%% and manually modified by Dominik Müller . +%% +%% The original source files were: +%% +%% fhnwfactsheet.dtx (with options: `class') +%% Author: Raphael Frey +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{fhnwfactsheet}% + [2018/07/17 v1.0.1 PDF-LaTeX class for FHNW fact sheets] + + + +\newif\if@english +\newif\if@german +\newif\if@confidential +\newif\if@tocteam +\newif\if@tocprojtype +\newif\if@fspath +\DeclareOption{english}{\@englishtrue\@germanfalse} +\DeclareOption{german}{\@germantrue\@englishfalse} +\DeclareOption{deutsch}{\@germantrue\@englishfalse} +\DeclareOption{confidential}{\@confidentialtrue} +\DeclareOption{tocteam}{\@tocteamtrue} +\DeclareOption{tocprojtype}{\@tocprojtypetrue} +\DeclareOption{fspath}{\@fspathtrue} +\DeclareOption*{% Fallback + \ClassError{myclass}{Unknown option '\CurrentOption'} +} +\ExecuteOptions{english,german,deutsch} % default options +\ProcessOptions +\LoadClass{report} +\RequirePackage[utf8]{inputenc} +\RequirePackage[T1]{fontenc} +\RequirePackage{graphicx} +\RequirePackage{tikz} +\RequirePackage{rviewport} +\RequirePackage{multicol} +\RequirePackage[inline]{enumitem} +\RequirePackage{geometry} +\if@confidential + \RequirePackage{draftwatermark} + \if@english + \SetWatermarkText{Confidential} + \fi + \if@german + \SetWatermarkText{Vertraulich} + \fi +\fi +\RequirePackage[scaled=0.95]{helvet} +\renewcommand\familydefault{\sfdefault} +\RequirePackage{xcolor} +\definecolor{parties}{HTML}{666666} +\definecolor{title}{HTML}{000066} +\definecolor{summary}{HTML}{666666} +\colorlet{boxbg}{cyan!50!blue!20!white} +\RequirePackage{rotating} +\RequirePackage{microtype} +\RequirePackage{tcolorbox} +\RequirePackage{booktabs} +\RequirePackage[binary-units=true]{siunitx} +\sisetup{range-phrase=--} +\RequirePackage[% + hidelinks=true, + bookmarksnumbered=true]{hyperref} +\if@english + \RequirePackage[english]{babel} +\fi +\if@german + \RequirePackage[ngerman]{babel} +\fi +\geometry{a4paper,twoside=false} +\newlength{\factpageouter} +\newlength{\factpageinner} +\newlength{\factpagetop} +\newlength{\factpagebottom} +\newlength{\factpagewidth} +\newlength{\factgraphicswidth} +\newlength{\testl} +\setlength{\factpageouter}{25mm} +\setlength{\factpageinner}{25mm} +\setlength{\factpagetop}{8mm} +\setlength{\factpagebottom}{30mm} +\setlength{\factpagewidth}{\paperwidth} +\addtolength{\factpagewidth}{-\factpageinner} +\addtolength{\factpagewidth}{-\factpageouter} +\setlength{\factgraphicswidth}{50mm} +\geometry{outer=\factpageouter,inner=\factpageinner,% + top=\factpagetop, bottom=\factpagebottom} + +\let\newcol\newpage +\newsavebox\fs@pagenumberbox +\newenvironment{factpage} + {\noindent\begin{minipage}[t][0pt]{\factpagewidth}} + {\end{minipage}} +\renewcommand\section{\@startsection {section}{1}{\z@}% + {-2.5ex \@plus -1ex \@minus -.2ex}% + {1ex}% + %{1ex \@plus.2ex}% default + {\large\bfseries\color{title}}*} +\let\subsection\@undefined +\let\subsubsection\@undefined +\let\paragraph\@undefined +\let\subparagraph\@undefined +\iflanguage{english}{% + \newcommand*{\lang@team} {\textbf{Team: }} + \newcommand*{\lang@client} {\textbf{Client: }} + \newcommand*{\lang@coach} {\textbf{Coach: }} + \newcommand*{\lang@coaches} {\textbf{Coaches: }} + \newcommand*{\lang@expert} {\textbf{Expert: }} + \newcommand*{\lang@experts} {\textbf{Experts: }} + \newcommand*{\lang@partner} {\textbf{Industry Partner: }} + \newcommand*{\lang@partners}{\textbf{Industry Partners: }} + \newcommand*{\lang@repo} {\textbf{Repository: }} + \newcommand*{\lang@source} {\textit{Source: }} +}{} +\iflanguage{ngerman}{% + \newcommand*{\lang@team} {\textbf{Arbeitsgruppe: }} + \newcommand*{\lang@client} {\textbf{Auftraggeber: }} + \newcommand*{\lang@coach} {\textbf{Betreuer: }} + \newcommand*{\lang@coaches} {\textbf{Betreuer: }} + \newcommand*{\lang@expert} {\textbf{Experte: }} + \newcommand*{\lang@experts} {\textbf{Experten: }} + \newcommand*{\lang@partner} {\textbf{Industriepartner: }} + \newcommand*{\lang@partners}{\textbf{Industriepartner: }} + \newcommand*{\lang@repo} {\textbf{Repository: }} + \newcommand*{\lang@source} {\textit{Quelle: }} +}{} +\newcommand*{\team}[1] + {% + \gdef\@team {% + {% + \footnotesize\color{parties}% + \lang@team% + #1% + } + }% + \if@tocteam\gdef\@tocteam {#1}\fi% + } +\newcommand*{\client}[1] + {\gdef\@client {{\footnotesize\color{parties}\lang@client#1}}} +\newcommand*{\coach}[1] + {\gdef\@coach {{\footnotesize\color{parties}\lang@coach#1}}} +\newcommand*{\coaches}[1] + {\gdef\@coaches {{\footnotesize\color{parties}\lang@coaches#1}}} +\newcommand*{\expert}[1] + {\gdef\@expert {{\footnotesize\color{parties}\lang@expert#1}}} +\newcommand*{\experts}[1] + {\gdef\@experts {{\footnotesize\color{parties}\lang@experts#1}}} +\newcommand*{\partner}[1] + {\gdef\@partner {{\footnotesize\color{parties}\lang@partner#1}}} +\newcommand*{\partners}[1] + {\gdef\@partners{{\footnotesize\color{parties}\lang@partners#1}}} +\newcommand*{\repo}[1] + {\gdef\@repo {{\footnotesize\color{parties}\lang@repo#1}}} +\newcommand*{\projtype}[1] + {\if@tocprojtype\gdef\@projtype{#1}\fi} +\renewcommand\maketitle{\par + \begingroup + {\Huge\color{title}\@title}\par + \vspace{2em} + \global\let\maketitle\relax + \global\let\@maketitle\relax + \global\let\title\relax + \global\let\date\relax + \global\let\@title\@empty + \global\let\@date\@empty + \endgroup +} +\newlength{\placeholderbase} +\newcommand\placeholderpics{% + \setlength{\placeholderbase}{48mm} + \begin{tikzpicture}[x=\placeholderbase,y=\placeholderbase,draw=black!50!white,very thick] + \draw (0,0) -- (1.618,1); + \draw (0,1) -- (1.618,0); + \draw (0,0) -- (1.618,0) -- (1.618,1) -- (0,1) -- cycle; + \node[draw,fill=white] at (0.809,0.5) {\large Beautiful Picture!}; + \end{tikzpicture} + \begin{tikzpicture}[x=\placeholderbase,y=\placeholderbase,draw=black!50!white,very thick] + \draw (0,0) -- (1.618,1); + \draw (0,1) -- (1.618,0); + \draw (0,0) -- (1.618,0) -- (1.618,1) -- (0,1) -- cycle; + \node[draw,fill=white] at (0.809,0.5) {\large Amazing Graphics!}; + \end{tikzpicture}\par + {\footnotesize Beautiful Picture and Amazing Graphics} +} +\newcommand\fscontent[1]{\gdef\fs@content{\graphicspath{\fs@graphicspath}#1}} +\newcommand\fs@makecontent{\par + \vspace{1em}\begin{multicols}{3} + \ifdef{\fs@content}{\fs@content}\par + \end{multicols} +} +\newcommand\fssummary[1]{\gdef\fs@summary{#1}} +\newcommand\fs@makesummary{\par + \vspace{0.25em}\noindent\begin{minipage}{\textwidth}\large + \ifdef{\fs@summary}{\color{summary}\fs@summary}\par + \end{minipage}% +} +\newcommand\fsgraphics[1]{\gdef\fs@graphics{\graphicspath{\fs@graphicspath}#1}} +\newcommand\graphicssource[1]{\gdef\fs@graphicssource{#1}} +\newcommand\graphicscaption[1]{\mbox{#1}} +\newcommand\fs@makegraphics{\par + \vspace{1em}\noindent\begin{minipage}[b]{\textwidth}% + \footnotesize\raggedright + \ifdef{\fs@graphics}{\fs@graphics}\par\par + \ifdef{\fs@graphicscaption}{\fs@graphicscaption}\par + \end{minipage}% + \begin{minipage}[t]{2ex}\footnotesize\color{parties} + \ifdef{\fs@graphicssource}{% + \hspace*{2ex}% + \turnbox{90}{% + \hspace*{2ex} \lang@source \fs@graphicssource}}\par + \end{minipage}% +} +\newcommand\infobox[2]{% + \gdef\fs@infoboxtitle{#1}% + \gdef\fs@infoboxcontent{\graphicspath{\fs@graphicspath}\footnotesize #2}% +} +\newcommand\fs@makeinfobox{ + \begin{tcolorbox}[ + title=\fs@infoboxtitle, + width=0.66\textwidth, + arc=0mm, + before=, + after=\hfill] + \fs@infoboxcontent + \end{tcolorbox} +} +\newcommand\tightlist{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}% +} +\newcommand\fs@checkinput{% + \ifdef{\@coach}{% + \ifdef{\@coaches}{% + \ClassError{fhnwfactsheet}{Both 'coach' and 'coaches' field defined. Undefine one.} + {Both the 'coach' and the 'coaches' field are defined. Only one of them should be.} + }{}% + }{}% + \ifdef{\@expert}{% + \ifdef{\@experts}{% + \ClassError{fhnwfactsheet}{Both 'expert' and 'experts' field defined. Undefine one.} + {Both the 'expert' and the 'experts' field are defined. Only one of them should be.} + }{}% + }{}% + \ifdef{\@partner}{% + \ifdef{\@partners}{% + \ClassError{fhnwfactsheet}{Both 'partner' and 'partners' field defined. Undefine one.} + {Both the 'partner' and the 'partners' field are defined. Only one of them should be.} + }{}% + }{}% + \ifdef{\fs@infoboxcontent}{} + {% + \ClassError{fhnwfactsheet}{Did you forget to specify your infobox?} + {The infobox contents are not defined. Make sure your infobox command is properly called.} + }% + \ifdef{\fs@infoboxtitle}{} + {% + \ClassError{fhnwfactsheet}{Did you forget to specify your infobox?} + {The infobox title is not defined. Make sure your infobox command is properly called.} + }% +} +\renewcommand\chapter{%\if@openright\cleardoublepage\else\clearpage\fi + \thispagestyle{plain}% + \global\@topnum\z@ + \@afterindentfalse + \secdef\@chapter\@schapter} +\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne + \refstepcounter{chapter}% + \typeout{\@chapapp\space\thechapter.}% + \addcontentsline{toc}{chapter}{#1}% + %{\protect\numberline{\thechapter}#1}% + \else + \addcontentsline{toc}{chapter}{#1}% + \fi + \chaptermark{#1}% + \addtocontents{lof}{\protect\addvspace{10\p@}}% + \addtocontents{lot}{\protect\addvspace{10\p@}}% + \if@twocolumn + \@topnewpage[\@makechapterhead{#2}]% + \else + \@makechapterhead{#2}% + \@afterheading + \fi} +\def\@makechapterhead#1{% + \begingroup + \mbox{\Huge\color{title}#1}\par + \vspace{2em} + \endgroup +} +\def\@makeschapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedright + \normalfont + \interlinepenalty\@M + \Huge\color{title} #1\par\nobreak + \vskip 40\p@ + }} +\renewcommand*\l@chapter[2]{% + \ifnum \c@tocdepth >\m@ne + \addpenalty{-\@highpenalty}% + \vskip 1.0em \@plus\p@ + \setlength\@tempdima{1.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode + \advance\leftskip\@tempdima + \hskip -\leftskip + %\@dottedtocline{0}{0em}{0em}{#1}{#2}\par + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \penalty\@highpenalty + \endgroup + \fi} +\newcommand*\includefactsheet[2][]{% + \input{#1#2}% + \if@fspath% + \sbox{\fs@pagenumberbox}{\thepage} + \gdef\fs@factsheetdirectory{#1}% + \fi% + \gdef\fs@graphicspath{#1}% + \makefactsheet% + \newpage} +\newcommand\makefactsheet{% + \begin{factpage} + \fs@checkinput + \chapter + [\ifdef{\@tocteam}{\@tocteam: }{}\@title\ifdef{\@projtype}{ \textbf{(\@projtype)}}{}] + {\@title} + % Must be after \chapter + % Note: We do not want to overwrite the \chapter pagestyle{plain} everywhere. + \thispagestyle{empty} + \fs@makesummary + \vspace{1ex} + \fs@makegraphics + \vspace{1ex} + \fs@makecontent + \vspace{1ex} + \tcbset{ + colback=boxbg, + colframe=title, + boxrule=0.5pt, + toptitle=2pt, + bottomtitle=1pt, + titlerule=0.5pt, + } + \fs@makeinfobox + \begin{minipage}[b]{0.30\textwidth} + \ifdef{\@team}{\@team}{}\par + \ifdef{\@client}{\@client}{}\par + \ifdef{\@coach}{\@coach}{}\par + \ifdef{\@coaches}{\@coaches}{}\par + \ifdef{\@expert}{\@expert}{}\par + \ifdef{\@experts}{\@experts}{}\par + \ifdef{\@partner}{\@partner}{}\par + \ifdef{\@partners}{\@partners}{}\par + \ifdef{\@repo}{\@repo}{}\par + \end{minipage} + \end{factpage}% + \raisebox{6ex}{% + \hspace{3em}% + \thepage% + \if@fspath% + \hspace{-\textwidth}% + \hspace{-3em}% + \hspace{-\wd\fs@pagenumberbox}% + {\color{parties}\fs@factsheetdirectory}% + \fi} + % Undefine for next fact sheet + \let\fs@graphics\@undefined + \let\fs@graphicssource\@undefined + \let\fs@graphicscaption\@undefined + \let\@team\@undefined + \let\@tocteam\@undefined + \let\fs@factsheetdirectory\@undefined + \let\@projtype\@undefined + \let\@client\@undefined + \let\@coach\@undefined + \let\@coaches\@undefined + \let\@expert\@undefined + \let\@experts\@undefined + \let\@partner\@undefined + \let\@partners\@undefined + \let\@repo\@undefined + \let\fs@infoboxtitle\@undefined + \let\fs@infoboxcontent\@undefined +} +\endinput +%% +%% End of file `fhnwfactsheet.cls'. diff --git a/doc/fact-sheet/graphics/1574943825_125_8_hand-featherball.png b/doc/fact-sheet/graphics/1574943825_125_8_hand-featherball.png new file mode 100644 index 0000000..fe3b081 Binary files /dev/null and b/doc/fact-sheet/graphics/1574943825_125_8_hand-featherball.png differ diff --git a/doc/fact-sheet/graphics/1574952009_278_10_stuffed-bunny.png b/doc/fact-sheet/graphics/1574952009_278_10_stuffed-bunny.png new file mode 100644 index 0000000..bc3fb5b Binary files /dev/null and b/doc/fact-sheet/graphics/1574952009_278_10_stuffed-bunny.png differ diff --git a/doc/fact-sheet/graphics/top_assembly.png b/doc/fact-sheet/graphics/top_assembly.png new file mode 100644 index 0000000..8bfe4bc Binary files /dev/null and b/doc/fact-sheet/graphics/top_assembly.png differ