This commit is contained in:
parent
91e0f9264f
commit
6d8e21bb80
644
converters/diagrams.lua
Normal file
644
converters/diagrams.lua
Normal file
@ -0,0 +1,644 @@
|
||||
--[[
|
||||
diagram – create images and figures from code blocks.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright © 2019-2023 Albert Krewinkel
|
||||
Copyright © 2019 Thorsten Sommer
|
||||
Copyright © 2018 Florian Schätzig
|
||||
Copyright © 2018 John MacFarlane
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
-- The filter uses the Figure AST element, which was added in pandoc 3.
|
||||
PANDOC_VERSION:must_be_at_least '3.0'
|
||||
|
||||
local version = pandoc.types.Version '1.2.0'
|
||||
|
||||
-- Report Lua warnings to stderr if the `warn` function is not plugged into
|
||||
-- pandoc's logging system.
|
||||
if not warn then
|
||||
-- fallback
|
||||
warn = function(...) io.stderr:write(table.concat({ ... })) end
|
||||
elseif PANDOC_VERSION < '3.1.4' then
|
||||
-- starting with pandoc 3.1.4, warnings are reported to pandoc's logging
|
||||
-- system, so no need to print warnings to stderr.
|
||||
warn '@on'
|
||||
end
|
||||
|
||||
local io = require 'io'
|
||||
local pandoc = require 'pandoc'
|
||||
local system = require 'pandoc.system'
|
||||
local utils = require 'pandoc.utils'
|
||||
local List = require 'pandoc.List'
|
||||
local stringify = utils.stringify
|
||||
local with_temporary_directory = system.with_temporary_directory
|
||||
local with_working_directory = system.with_working_directory
|
||||
|
||||
--- Returns a filter-specific directory in which cache files can be
|
||||
--- stored, or nil if no such directory is available.
|
||||
local function cachedir ()
|
||||
local cache_home = os.getenv 'XDG_CACHE_HOME'
|
||||
if not cache_home or cache_home == '' then
|
||||
local user_home = system.os == 'windows'
|
||||
and os.getenv 'USERPROFILE'
|
||||
or os.getenv 'HOME'
|
||||
|
||||
if not user_home or user_home == '' then
|
||||
return nil
|
||||
end
|
||||
cache_home = pandoc.path.join{user_home, '.cache'} or nil
|
||||
end
|
||||
|
||||
-- Create filter cache directory
|
||||
return pandoc.path.join{cache_home, 'pandoc-diagram-filter'}
|
||||
end
|
||||
|
||||
--- Path holding the image cache, or `nil` if the cache is not used.
|
||||
local image_cache = nil
|
||||
|
||||
local mimetype_for_extension = {
|
||||
jpeg = 'image/jpeg',
|
||||
jpg = 'image/jpeg',
|
||||
pdf = 'application/pdf',
|
||||
png = 'image/png',
|
||||
svg = 'image/svg+xml',
|
||||
}
|
||||
|
||||
local extension_for_mimetype = {
|
||||
['application/pdf'] = 'pdf',
|
||||
['image/jpeg'] = 'jpg',
|
||||
['image/png'] = 'png',
|
||||
['image/svg+xml'] = 'svg',
|
||||
}
|
||||
|
||||
--- Converts a list of format specifiers to a set of MIME types.
|
||||
local function mime_types_set (tbl)
|
||||
local set = {}
|
||||
local mime_type
|
||||
for _, image_format_spec in ipairs(tbl) do
|
||||
mime_type = mimetype_for_extension[image_format_spec] or image_format_spec
|
||||
set[mime_type] = true
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
--- Reads the contents of a file.
|
||||
local function read_file (filepath)
|
||||
local fh = io.open(filepath, 'rb')
|
||||
local contents = fh:read('a')
|
||||
fh:close()
|
||||
return contents
|
||||
end
|
||||
|
||||
--- Writes the contents into a file at the given path.
|
||||
local function write_file (filepath, content)
|
||||
local fh = io.open(filepath, 'wb')
|
||||
fh:write(content)
|
||||
fh:close()
|
||||
end
|
||||
|
||||
--- Like `pandoc.pipe`, but allows "multi word" paths:
|
||||
-- Supplying a list as the first argument will use the first element as
|
||||
-- the executable path and prepend the remaining elements to the list of
|
||||
-- arguments.
|
||||
local function pipe (command, args, input)
|
||||
local cmd
|
||||
if pandoc.utils.type(command) == 'List' then
|
||||
command = command:map(stringify)
|
||||
cmd = command:remove(1)
|
||||
args = command .. args
|
||||
else
|
||||
cmd = stringify(command)
|
||||
end
|
||||
return pandoc.pipe(cmd, args, input)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Diagram Engines
|
||||
--
|
||||
|
||||
-- PlantUML engine; assumes that there's a `plantuml` binary.
|
||||
local plantuml = {
|
||||
line_comment_start = [[']],
|
||||
mime_types = mime_types_set{'pdf', 'png', 'svg'},
|
||||
compile = function (self, puml)
|
||||
local mime_type = self.mime_type or 'image/svg+xml'
|
||||
-- PlantUML format identifiers correspond to common file extensions.
|
||||
local format = extension_for_mimetype[mime_type]
|
||||
if not format then
|
||||
format, mime_type = 'svg', 'image/svg+xml'
|
||||
end
|
||||
local args = {'-t' .. format, "-pipe", "-charset", "UTF8"}
|
||||
return pipe(self.execpath or 'plantuml', args, puml), mime_type
|
||||
end,
|
||||
}
|
||||
|
||||
--- GraphViz engine for the dot language
|
||||
local graphviz = {
|
||||
line_comment_start = '//',
|
||||
mime_types = mime_types_set{'jpg', 'pdf', 'png', 'svg'},
|
||||
mime_type = 'image/svg+xml',
|
||||
compile = function (self, code)
|
||||
local mime_type = self.mime_type
|
||||
-- GraphViz format identifiers correspond to common file extensions.
|
||||
local format = extension_for_mimetype[mime_type]
|
||||
if not format then
|
||||
format, mime_type = 'svg', 'image/svg+xml'
|
||||
end
|
||||
return pipe(self.execpath or 'dot', {"-T"..format}, code), mime_type
|
||||
end,
|
||||
}
|
||||
|
||||
--- Mermaid engine
|
||||
local mermaid = {
|
||||
line_comment_start = '%%',
|
||||
mime_types = mime_types_set{'pdf', 'png', 'svg'},
|
||||
compile = function (self, code)
|
||||
local mime_type = self.mime_type or 'image/svg+xml'
|
||||
local file_extension = extension_for_mimetype[mime_type]
|
||||
return with_temporary_directory("diagram", function (tmpdir)
|
||||
return with_working_directory(tmpdir, function ()
|
||||
local infile = 'diagram.mmd'
|
||||
local outfile = 'diagram.' .. file_extension
|
||||
write_file(infile, code)
|
||||
pipe(
|
||||
self.execpath or 'mmdc',
|
||||
{"--pdfFit", "--input", infile, "--output", outfile},
|
||||
''
|
||||
)
|
||||
return read_file(outfile), mime_type
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
--- TikZ
|
||||
--
|
||||
|
||||
--- LaTeX template used to compile TikZ images.
|
||||
local tikz_template = pandoc.template.compile [[
|
||||
\documentclass{standalone}
|
||||
\usepackage{tikz}
|
||||
$for(header-includes)$
|
||||
$it$
|
||||
$endfor$
|
||||
$additional-packages$
|
||||
\begin{document}
|
||||
$body$
|
||||
\end{document}
|
||||
]]
|
||||
|
||||
--- The TikZ engine uses pdflatex to compile TikZ code to an image
|
||||
local tikz = {
|
||||
line_comment_start = '%%',
|
||||
|
||||
mime_types = {
|
||||
['application/pdf'] = true,
|
||||
},
|
||||
|
||||
--- Compile LaTeX with TikZ code to an image
|
||||
compile = function (self, src, user_opts)
|
||||
return with_temporary_directory("tikz", function (tmpdir)
|
||||
return with_working_directory(tmpdir, function ()
|
||||
-- Define file names:
|
||||
local file_template = "%s/tikz-image.%s"
|
||||
local tikz_file = file_template:format(tmpdir, "tex")
|
||||
local pdf_file = file_template:format(tmpdir, "pdf")
|
||||
|
||||
-- Treat string values as raw LaTeX
|
||||
local meta = {
|
||||
['header-includes'] = user_opts['header-includes'],
|
||||
['additional-packages'] = {pandoc.RawInline(
|
||||
'latex',
|
||||
stringify(user_opts['additional-packages'] or '')
|
||||
)},
|
||||
}
|
||||
local tex_code = pandoc.write(
|
||||
pandoc.Pandoc({pandoc.RawBlock('latex', src)}, meta),
|
||||
'latex',
|
||||
{template = tikz_template}
|
||||
)
|
||||
write_file(tikz_file, tex_code)
|
||||
|
||||
-- Execute the LaTeX compiler:
|
||||
local success, result = pcall(
|
||||
pipe,
|
||||
self.execpath or 'pdflatex',
|
||||
{ '-interaction=nonstopmode', '-output-directory', tmpdir, tikz_file },
|
||||
''
|
||||
)
|
||||
if not success then
|
||||
warn(string.format(
|
||||
"The call\n%s\nfailed with error code %s. Output:\n%s",
|
||||
result.command,
|
||||
result.error_code,
|
||||
result.output
|
||||
))
|
||||
end
|
||||
return read_file(pdf_file), 'application/pdf'
|
||||
end)
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
--- Asymptote diagram engine
|
||||
local asymptote = {
|
||||
line_comment_start = '%%',
|
||||
mime_types = {
|
||||
['application/pdf'] = true,
|
||||
},
|
||||
compile = function (self, code)
|
||||
return with_temporary_directory("asymptote", function(tmpdir)
|
||||
return with_working_directory(tmpdir, function ()
|
||||
local pdf_file = "pandoc_diagram.pdf"
|
||||
local args = {'-tex', 'pdflatex', "-o", "pandoc_diagram", '-'}
|
||||
pipe(self.execpath or 'asy', args, code)
|
||||
return read_file(pdf_file), 'application/pdf'
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
--- Cetz diagram engine
|
||||
local cetz = {
|
||||
line_comment_start = '%%',
|
||||
mime_types = mime_types_set{'jpg', 'pdf', 'png', 'svg'},
|
||||
mime_type = 'image/svg+xml',
|
||||
compile = function (self, code)
|
||||
local mime_type = self.mime_type
|
||||
local format = extension_for_mimetype[mime_type]
|
||||
if not format then
|
||||
format, mime_type = 'svg', 'image/svg+xml'
|
||||
end
|
||||
local preamble = [[
|
||||
#import "@preview/cetz:0.3.4"
|
||||
#set page(width: auto, height: auto, margin: .5cm)
|
||||
]]
|
||||
|
||||
local typst_code = preamble .. code
|
||||
|
||||
return with_temporary_directory("diagram", function (tmpdir)
|
||||
return with_working_directory(tmpdir, function ()
|
||||
local outfile = 'diagram.' .. format
|
||||
local execpath = self.execpath
|
||||
if not execpath and quarto and quarto.version >= '1.4' then
|
||||
-- fall back to the Typst exec shipped with Quarto.
|
||||
execpath = List{'quarto', 'typst'}
|
||||
end
|
||||
pipe(
|
||||
execpath or 'typst',
|
||||
{"compile", "-f", format, "-", outfile},
|
||||
typst_code
|
||||
)
|
||||
return read_file(outfile), mime_type
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
local default_engines = {
|
||||
asymptote = asymptote,
|
||||
dot = graphviz,
|
||||
mermaid = mermaid,
|
||||
plantuml = plantuml,
|
||||
tikz = tikz,
|
||||
cetz = cetz,
|
||||
}
|
||||
|
||||
--
|
||||
-- Configuration
|
||||
--
|
||||
|
||||
--- Options for the output format of the given name.
|
||||
local function format_options (name)
|
||||
local pdf2svg = name ~= 'latex' and name ~= 'context'
|
||||
local is_office_format = name == 'docx' or name == 'odt'
|
||||
-- Office formats seem to work better with PNG than with SVG.
|
||||
local preferred_mime_types = is_office_format
|
||||
and pandoc.List{'image/png', 'application/pdf'}
|
||||
or pandoc.List{'application/pdf', 'image/png'}
|
||||
-- Prefer SVG for non-PDF output formats, except for Office formats
|
||||
if is_office_format then
|
||||
preferred_mime_types:insert('image/svg+xml')
|
||||
elseif pdf2svg then
|
||||
preferred_mime_types:insert(1, 'image/svg+xml')
|
||||
end
|
||||
return {
|
||||
name = name,
|
||||
pdf2svg = pdf2svg,
|
||||
preferred_mime_types = preferred_mime_types,
|
||||
best_mime_type = function (self, supported_mime_types, requested)
|
||||
return self.preferred_mime_types:find_if(function (preferred)
|
||||
return supported_mime_types[preferred] and
|
||||
(not requested or
|
||||
(pandoc.utils.type(requested) == 'List' and
|
||||
requested:includes(preferred)) or
|
||||
(pandoc.utils.type(requested) == 'table' and
|
||||
requested[preferred]) or
|
||||
|
||||
-- Assume string, Inlines, and Blocks values specify the only
|
||||
-- acceptable MIME type.
|
||||
stringify(requested) == preferred)
|
||||
end)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
--- Returns a configured diagram engine.
|
||||
local function get_engine (name, engopts, format)
|
||||
local engine = default_engines[name] or
|
||||
select(2, pcall(require, stringify(engopts.package)))
|
||||
|
||||
-- Sanity check
|
||||
if not engine then
|
||||
warn(PANDOC_SCRIPT_FILE, ": No such engine '", name, "'.")
|
||||
return nil
|
||||
elseif engopts == false then
|
||||
-- engine is disabled
|
||||
return nil
|
||||
elseif engopts == true then
|
||||
-- use default options
|
||||
return engine
|
||||
end
|
||||
|
||||
local execpath = engopts.execpath or os.getenv(name:upper() .. '_BIN')
|
||||
|
||||
local mime_type = format:best_mime_type(
|
||||
engine.mime_types,
|
||||
engopts['mime-type'] or engopts['mime-types']
|
||||
)
|
||||
if not mime_type then
|
||||
warn(PANDOC_SCRIPT_FILE, ": Cannot use ", name, " with ", format.name)
|
||||
return nil
|
||||
end
|
||||
|
||||
return {
|
||||
execpath = execpath,
|
||||
compile = engine.compile,
|
||||
line_comment_start = engine.line_comment_start,
|
||||
mime_type = mime_type,
|
||||
opt = engopts or {},
|
||||
}
|
||||
end
|
||||
|
||||
--- Returns the diagram engine configs.
|
||||
local function configure (meta, format_name)
|
||||
local conf = meta.diagram or {}
|
||||
local format = format_options(format_name)
|
||||
meta.diagram = nil
|
||||
|
||||
-- cache for image files
|
||||
if conf.cache then
|
||||
image_cache = conf['cache-dir']
|
||||
and stringify(conf['cache-dir'])
|
||||
or cachedir()
|
||||
pandoc.system.make_directory(image_cache, true)
|
||||
end
|
||||
|
||||
-- engine configs
|
||||
local engine = {}
|
||||
for name, engopts in pairs(conf.engine or default_engines) do
|
||||
engine[name] = get_engine(name, engopts, format)
|
||||
end
|
||||
|
||||
return {
|
||||
engine = engine,
|
||||
format = format,
|
||||
cache = image_cache and true,
|
||||
image_cache = image_cache,
|
||||
}
|
||||
end
|
||||
|
||||
--
|
||||
-- Format conversion
|
||||
--
|
||||
|
||||
--- Converts a PDF to SVG.
|
||||
local pdf2svg = function (imgdata)
|
||||
-- Using `os.tmpname()` instead of a hash would be slightly cleaner, but the
|
||||
-- function causes problems on Windows (and wasm). See, e.g.,
|
||||
-- https://github.com/pandoc-ext/diagram/issues/49
|
||||
local pdf_file = 'diagram-' .. pandoc.utils.sha1(imgdata) .. '.pdf'
|
||||
write_file(pdf_file, imgdata)
|
||||
local args = {
|
||||
'--export-type=svg',
|
||||
'--export-plain-svg',
|
||||
'--export-filename=-',
|
||||
pdf_file
|
||||
}
|
||||
return pandoc.pipe('inkscape', args, ''), os.remove(pdf_file)
|
||||
end
|
||||
|
||||
local function properties_from_code (code, comment_start)
|
||||
local props = {}
|
||||
local pattern = comment_start:gsub('%p', '%%%1') .. '| ' ..
|
||||
'([-_%w]+): ([^\n]*)\n'
|
||||
for key, value in code:gmatch(pattern) do
|
||||
if key == 'fig-cap' then
|
||||
props['caption'] = value
|
||||
else
|
||||
props[key] = value
|
||||
end
|
||||
end
|
||||
return props
|
||||
end
|
||||
|
||||
local function diagram_options (cb, comment_start)
|
||||
local attribs = comment_start
|
||||
and properties_from_code(cb.text, comment_start)
|
||||
or {}
|
||||
for key, value in pairs(cb.attributes) do
|
||||
attribs[key] = value
|
||||
end
|
||||
|
||||
local alt
|
||||
local caption
|
||||
local fig_attr = {id = cb.identifier}
|
||||
local filename
|
||||
local image_attr = {}
|
||||
local user_opt = {}
|
||||
|
||||
for attr_name, value in pairs(attribs) do
|
||||
if attr_name == 'alt' then
|
||||
alt = value
|
||||
elseif attr_name == 'caption' then
|
||||
-- Read caption attribute as Markdown
|
||||
caption = attribs.caption
|
||||
and pandoc.read(attribs.caption).blocks
|
||||
or nil
|
||||
elseif attr_name == 'filename' then
|
||||
filename = value
|
||||
elseif attr_name == 'label' then
|
||||
fig_attr.id = value
|
||||
elseif attr_name == 'name' then
|
||||
fig_attr.name = value
|
||||
else
|
||||
-- Check for prefixed attributes
|
||||
local prefix, key = attr_name:match '^(%a+)%-(%a[-%w]*)$'
|
||||
if prefix == 'fig' then
|
||||
fig_attr[key] = value
|
||||
elseif prefix == 'image' or prefix == 'img' then
|
||||
image_attr[key] = value
|
||||
elseif prefix == 'opt' then
|
||||
user_opt[key] = value
|
||||
else
|
||||
-- Use as image attribute
|
||||
image_attr[attr_name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
['alt'] = alt or
|
||||
(caption and pandoc.utils.blocks_to_inlines(caption)) or
|
||||
{},
|
||||
['caption'] = caption,
|
||||
['fig-attr'] = fig_attr,
|
||||
['filename'] = filename,
|
||||
['image-attr'] = image_attr,
|
||||
['opt'] = user_opt,
|
||||
}
|
||||
end
|
||||
|
||||
local function get_cached_image (hash, mime_type)
|
||||
if not image_cache then
|
||||
return nil
|
||||
end
|
||||
local filename = hash .. '.' .. extension_for_mimetype[mime_type]
|
||||
local imgpath = pandoc.path.join{image_cache, filename}
|
||||
local success, imgdata = pcall(read_file, imgpath)
|
||||
if success then
|
||||
return imgdata, mime_type
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function cache_image (codeblock, imgdata, mimetype)
|
||||
-- do nothing if caching is disabled or not possible.
|
||||
if not image_cache then
|
||||
return
|
||||
end
|
||||
local ext = extension_for_mimetype[mimetype]
|
||||
local filename = pandoc.sha1(codeblock.text) .. '.' .. ext
|
||||
local imgpath = pandoc.path.join{image_cache, filename}
|
||||
write_file(imgpath, imgdata)
|
||||
end
|
||||
|
||||
-- Executes each document's code block to find matching code blocks:
|
||||
local function code_to_figure (conf)
|
||||
return function (block)
|
||||
-- Check if a converter exists for this block. If not, return the block
|
||||
-- unchanged.
|
||||
local diagram_type = block.classes[1]
|
||||
if not diagram_type then
|
||||
return nil
|
||||
end
|
||||
|
||||
local engine = conf.engine[diagram_type]
|
||||
if not engine then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Unified properties.
|
||||
local dgr_opt = diagram_options(block, engine.line_comment_start)
|
||||
for optname, value in pairs(engine.opt or {}) do
|
||||
dgr_opt.opt[optname] = dgr_opt.opt[optname] or value
|
||||
end
|
||||
|
||||
local run_pdf2svg = engine.mime_type == 'application/pdf'
|
||||
and conf.format.pdf2svg
|
||||
|
||||
-- Try to retrieve the image data from the cache.
|
||||
local imgdata, imgtype
|
||||
if conf.cache then
|
||||
imgdata, imgtype = get_cached_image(
|
||||
pandoc.sha1(block.text),
|
||||
run_pdf2svg and 'image/svg+xml' or engine.mime_type
|
||||
)
|
||||
end
|
||||
|
||||
if not imgdata or not imgtype then
|
||||
-- No cached image; call the converter
|
||||
local success
|
||||
success, imgdata, imgtype =
|
||||
pcall(engine.compile, engine, block.text, dgr_opt.opt)
|
||||
|
||||
-- Bail if an error occurred; imgdata contains the error message
|
||||
-- when that happens.
|
||||
if not success then
|
||||
warn(PANDOC_SCRIPT_FILE, ': ', tostring(imgdata))
|
||||
return nil
|
||||
elseif not imgdata then
|
||||
warn(PANDOC_SCRIPT_FILE, ': Diagram engine returned no image data.')
|
||||
return nil
|
||||
elseif not imgtype then
|
||||
warn(PANDOC_SCRIPT_FILE, ': Diagram engine did not return a MIME type.')
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Convert SVG if necessary.
|
||||
if imgtype == 'application/pdf' and conf.format.pdf2svg then
|
||||
imgdata, imgtype = pdf2svg(imgdata), 'image/svg+xml'
|
||||
end
|
||||
|
||||
-- If we got here, then the transformation went ok and `img` contains
|
||||
-- the image data.
|
||||
cache_image(block, imgdata, imgtype)
|
||||
end
|
||||
|
||||
-- Use the block's filename attribute or create a new name by hashing the
|
||||
-- image content.
|
||||
local basename, _extension = pandoc.path.split_extension(
|
||||
dgr_opt.filename or pandoc.sha1(imgdata)
|
||||
)
|
||||
local fname = basename .. '.' .. extension_for_mimetype[imgtype]
|
||||
|
||||
-- Store the data in the media bag:
|
||||
pandoc.mediabag.insert(fname, imgtype, imgdata)
|
||||
|
||||
-- Create the image object.
|
||||
local image = pandoc.Image(dgr_opt.alt, fname, "", dgr_opt['image-attr'])
|
||||
|
||||
-- Create a figure if the diagram has a caption; otherwise return
|
||||
-- just the image.
|
||||
return dgr_opt.caption and
|
||||
pandoc.Figure(
|
||||
pandoc.Plain{image},
|
||||
dgr_opt.caption,
|
||||
dgr_opt['fig-attr']
|
||||
) or
|
||||
pandoc.Plain{image}
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable(
|
||||
{{
|
||||
Pandoc = function (doc)
|
||||
local conf = configure(doc.meta, FORMAT)
|
||||
return doc:walk {
|
||||
CodeBlock = code_to_figure(conf),
|
||||
}
|
||||
end
|
||||
}},
|
||||
{
|
||||
version = version,
|
||||
}
|
||||
)
|
||||
@ -9,7 +9,21 @@ mkdir -p "$(dirname "$TEMP_MD_FILE")"
|
||||
|
||||
cp "$MD_FILE" "$TEMP_MD_FILE"
|
||||
|
||||
for line in $(grep '^!\[.*\](.*\.md)$' "$TEMP_MD_FILE" | sed 's/ /%20;/g')
|
||||
function download_images() {
|
||||
echo "download images for $1"
|
||||
for line in $(grep '!\[.*\](https://.*\.png)' "$1" | sed -e 's/ /%20;/g')
|
||||
do
|
||||
src=$(echo "$line" | sed -e 's/^.*(//' -e 's/).*$//' -e 's/%20;/ /g')
|
||||
echo "remote image found: $src"
|
||||
|
||||
mkdir -p "${BASE_DIR}/latex/images"
|
||||
name=$(echo "$src" | sed -e 's|^.*/\([^/]*\)$|\1|')
|
||||
curl "$src" > "${BASE_DIR}/latex/images/$name"
|
||||
done
|
||||
echo "download done"
|
||||
}
|
||||
|
||||
for line in $(grep '^!\[.*\](.*\.md)$' "$TEMP_MD_FILE" | sed -e 's/ /%20;/g')
|
||||
do
|
||||
src=$(echo "$line" | sed -e 's/^.*(//' -e 's/).*$//' -e 's/%20;/ /g')
|
||||
echo "include found: markdown/$src"
|
||||
@ -20,21 +34,16 @@ do
|
||||
-e 's|^\[parent\].*$||' \
|
||||
-e 's|^# |\\newpage\n# |' \
|
||||
-e 's|^## |\\newpage\n# |' \
|
||||
-e 's|\[\([^]]*\)\](#\([^)]*\))|[\1](#\L\2)|'
|
||||
-e 's|\[\([^]]*\)\](#\([^)]*\))|[\1](#\L\2)|' \
|
||||
-e 's|https://live.kladjes.nl/uploads|../../latex/images|'
|
||||
download_images "$BUILD_DIR/$src"
|
||||
|
||||
sed -i "$TEMP_MD_FILE" \
|
||||
-e "s/^\!\[.*\]($src)\$/\`\`\`\\{.include\\}\n${src}\n\`\`\`/"
|
||||
-e "s/^\!\[.*\]($src)\$/\`\`\`\\{.include shift-heading-level-by=1\\}\n${src}\n\`\`\`/"
|
||||
|
||||
done
|
||||
|
||||
for line in $(grep '!\[.*\](https://.*\.png)' "$TEMP_MD_FILE" | sed 's/ /%20;/g')
|
||||
do
|
||||
src=$(echo "$line" | sed -e 's/^.*(//' -e 's/).*$//' -e 's/%20;/ /g')
|
||||
echo "remote image found: $src"
|
||||
|
||||
mkdir -p "${BASE_DIR}/latex/images"
|
||||
name=$(echo "$src" | sed -e 's|^.*/\([^/]*\)$|\1|')
|
||||
curl "$src" > "${BASE_DIR}/latex/images/$name"
|
||||
done
|
||||
download_images "$TEMP_MD_FILE"
|
||||
|
||||
title="$(grep '^# ' "$MD_FILE" | head -n 1 | sed 's|^# ||')"
|
||||
|
||||
@ -45,10 +54,10 @@ sed -i "$TEMP_MD_FILE" \
|
||||
-e 's|^#||' \
|
||||
-e 's|^# |\\newpage\n# |' \
|
||||
-e 's|\[\([^]]*\)\](#\([^)]*\))|[\1](#\L\2)|' \
|
||||
-e 's|https://live.kladjes.nl/uploads|images|'
|
||||
-e 's|https://live.kladjes.nl/uploads|../../latex/images|'
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
pandoc --lua-filter=../../converters/include-files.lua --to=latex --from=markdown+abbreviations --template "${BASE_DIR}/converters/template.latex" -o "$TEX_FILE" --data-dir="../../markdown" "$(basename "$TEMP_MD_FILE")"
|
||||
pandoc --lua-filter=../../converters/include-files.lua --to=latex --from=markdown+abbreviations --template "${BASE_DIR}/converters/template.latex" -o "$TEX_FILE" "$(basename "$TEMP_MD_FILE")"
|
||||
cd "$BASE_DIR"
|
||||
|
||||
# for line in $(grep '^!\[.*\](.*\.md)$' "$TEMP_MD_FILE" | sed 's/ /%20;/g')
|
||||
|
||||
@ -79,9 +79,10 @@
|
||||
\lineskip .75em
|
||||
\begin{tabular}{r l}
|
||||
gemaakt door: & Finley van Reenen (0964590@hr.nl) \\
|
||||
& Gryvon Belfor (0985890@hr.nl) \\
|
||||
& Chris Tan (0992143@hr.nl) \\
|
||||
& Mohamed El Morabiti (1014780@hr.nl) \\\\
|
||||
& Tijn Snijders (1001829@hr.nl) \\
|
||||
& Max Kappert (1030682@hr.nl) \\
|
||||
& Thomas Braam (0989527@hr.nl) \\\\
|
||||
vak code: & ELEPEE51 \\\\
|
||||
ge\"exporteerd op: & \today
|
||||
\end{tabular}
|
||||
@ -94,7 +95,7 @@
|
||||
\fancyhead[LO]{\color{gray}\fontUbuntu ?title?}
|
||||
\fancyhead[RO]{\color{gray}\fontUbuntu Superlight Personal Carrier}
|
||||
\fancyfoot{} % clear all footer fields
|
||||
\fancyfoot[LO]{\color{gray}\fontUbuntu E.L.F. van Reenen, G. Belfor, C. Tan en M.E. Morabiti}
|
||||
\fancyfoot[LO]{\color{gray}\fontUbuntu E.L.F. van Reenen, C. Tan, T Snijders, M. Kappert en T. Braam}
|
||||
\fancyfoot[CO]{\color{gray}\fontUbuntu }
|
||||
\fancyfoot[RO]{\color{gray}\fontUbuntu \thepage}
|
||||
|
||||
|
||||
72
makefile
72
makefile
@ -1,5 +1,8 @@
|
||||
|
||||
all: prepare pdf/plan_van_aanpak.pdf pdf/plan_van_aanpak.booklet.pdf
|
||||
all: all_booklets all_docduments
|
||||
|
||||
all_docduments: prepare pdf/plan_van_aanpak.pdf pdf/detailontwerp_stabilisatie.pdf pdf/detailontwerp_stuursysteem.pdf pdf/unittest_stabilisatie.pdf pdf/projectdocument.pdf
|
||||
all_booklets: prepare pdf/plan_van_aanpak.booklet.pdf pdf/detailontwerp_stabilisatie.booklet.pdf pdf/detailontwerp_stuursysteem.booklet.pdf pdf/unittest_stabilisatie.booklet.pdf pdf/projectdocument.booklet.pdf
|
||||
|
||||
prepare:
|
||||
mkdir -p latex pdf
|
||||
@ -7,6 +10,9 @@ prepare:
|
||||
clean:
|
||||
rm -r build
|
||||
|
||||
clean_all:
|
||||
rm -r build latex pdf
|
||||
|
||||
install_arch:
|
||||
mkdir -p build/install
|
||||
pacman -Sy --noconfirm --needed curl unzip texlive-basic texlive-langeuropean pandoc
|
||||
@ -65,6 +71,22 @@ latex/pakket_van_eisen.latex: converters/mdToLatex.sh converters/template.latex
|
||||
mkdir -p build/pakket_van_eisen
|
||||
bash converters/mdToLatex.sh markdown/pakket_van_eisen.md latex/pakket_van_eisen.latex
|
||||
|
||||
latex/detailontwerp_stabilisatie.latex: converters/mdToLatex.sh converters/template.latex markdown/detailontwerp_stabilisatie.md
|
||||
mkdir -p build/detailontwerp_stabilisatie
|
||||
bash converters/mdToLatex.sh markdown/detailontwerp_stabilisatie.md latex/detailontwerp_stabilisatie.latex
|
||||
|
||||
latex/detailontwerp_stuursysteem.latex: converters/mdToLatex.sh converters/template.latex markdown/detailontwerp_stuursysteem.md
|
||||
mkdir -p build/detailontwerp_stuursysteem
|
||||
bash converters/mdToLatex.sh markdown/detailontwerp_stuursysteem.md latex/detailontwerp_stuursysteem.latex
|
||||
|
||||
latex/unittest_stabilisatie.latex: converters/mdToLatex.sh converters/template.latex markdown/unittest_stabilisatie.md
|
||||
mkdir -p build/unittest_stabilisatie
|
||||
bash converters/mdToLatex.sh markdown/unittest_stabilisatie.md latex/unittest_stabilisatie.latex
|
||||
|
||||
# latex/unittest_stuursysteem.latex: converters/mdToLatex.sh converters/template.latex markdown/unittest_stuursysteem.md
|
||||
# mkdir -p build/unittest_stuursysteem
|
||||
# bash converters/mdToLatex.sh markdown/unittest_stuursysteem.md latex/unittest_stuursysteem.latex
|
||||
|
||||
latex/projectdocument.latex: converters/mdToLatex.sh converters/template.latex markdown/projectdocument.md
|
||||
mkdir -p build/projectdocument
|
||||
bash converters/mdToLatex.sh markdown/projectdocument.md latex/projectdocument.latex
|
||||
@ -97,6 +119,54 @@ pdf/pakket_van_eisen.booklet.pdf: converters/bookletify.latex pdf/pakket_van_eis
|
||||
pdflatex -interaction=nonstopmode -output-directory="build/pakket_van_eisen.booklet" "build/pakket_van_eisen.booklet/bookletify.latex"
|
||||
mv build/pakket_van_eisen.booklet/bookletify.pdf pdf/pakket_van_eisen.booklet.pdf
|
||||
|
||||
pdf/detailontwerp_stabilisatie.pdf: latex/detailontwerp_stabilisatie.latex
|
||||
cd build/detailontwerp_stabilisatie && xelatex ../../latex/detailontwerp_stabilisatie.latex
|
||||
cd build/detailontwerp_stabilisatie && xelatex ../../latex/detailontwerp_stabilisatie.latex
|
||||
cd build/detailontwerp_stabilisatie && xelatex ../../latex/detailontwerp_stabilisatie.latex
|
||||
mv build/detailontwerp_stabilisatie/detailontwerp_stabilisatie.pdf pdf/detailontwerp_stabilisatie.pdf
|
||||
|
||||
pdf/detailontwerp_stabilisatie.booklet.pdf: converters/bookletify.latex pdf/detailontwerp_stabilisatie.pdf
|
||||
mkdir -p build/detailontwerp_stabilisatie.booklet
|
||||
sed -e 's|?pdf?|../../pdf/detailontwerp_stabilisatie.pdf|' converters/bookletify.latex >build/detailontwerp_stabilisatie.booklet/bookletify.latex
|
||||
pdflatex -interaction=nonstopmode -output-directory="build/detailontwerp_stabilisatie.booklet" "build/detailontwerp_stabilisatie.booklet/bookletify.latex"
|
||||
mv build/detailontwerp_stabilisatie.booklet/bookletify.pdf pdf/detailontwerp_stabilisatie.booklet.pdf
|
||||
|
||||
pdf/detailontwerp_stuursysteem.pdf: latex/detailontwerp_stuursysteem.latex
|
||||
cd build/detailontwerp_stuursysteem && xelatex ../../latex/detailontwerp_stuursysteem.latex
|
||||
cd build/detailontwerp_stuursysteem && xelatex ../../latex/detailontwerp_stuursysteem.latex
|
||||
cd build/detailontwerp_stuursysteem && xelatex ../../latex/detailontwerp_stuursysteem.latex
|
||||
mv build/detailontwerp_stuursysteem/detailontwerp_stuursysteem.pdf pdf/detailontwerp_stuursysteem.pdf
|
||||
|
||||
pdf/detailontwerp_stuursysteem.booklet.pdf: converters/bookletify.latex pdf/detailontwerp_stuursysteem.pdf
|
||||
mkdir -p build/detailontwerp_stuursysteem.booklet
|
||||
sed -e 's|?pdf?|../../pdf/detailontwerp_stuursysteem.pdf|' converters/bookletify.latex >build/detailontwerp_stuursysteem.booklet/bookletify.latex
|
||||
pdflatex -interaction=nonstopmode -output-directory="build/detailontwerp_stuursysteem.booklet" "build/detailontwerp_stuursysteem.booklet/bookletify.latex"
|
||||
mv build/detailontwerp_stuursysteem.booklet/bookletify.pdf pdf/detailontwerp_stuursysteem.booklet.pdf
|
||||
|
||||
pdf/unittest_stabilisatie.pdf: latex/unittest_stabilisatie.latex
|
||||
cd build/unittest_stabilisatie && xelatex ../../latex/unittest_stabilisatie.latex
|
||||
cd build/unittest_stabilisatie && xelatex ../../latex/unittest_stabilisatie.latex
|
||||
cd build/unittest_stabilisatie && xelatex ../../latex/unittest_stabilisatie.latex
|
||||
mv build/unittest_stabilisatie/unittest_stabilisatie.pdf pdf/unittest_stabilisatie.pdf
|
||||
|
||||
pdf/unittest_stabilisatie.booklet.pdf: converters/bookletify.latex pdf/unittest_stabilisatie.pdf
|
||||
mkdir -p build/unittest_stabilisatie.booklet
|
||||
sed -e 's|?pdf?|../../pdf/unittest_stabilisatie.pdf|' converters/bookletify.latex >build/unittest_stabilisatie.booklet/bookletify.latex
|
||||
pdflatex -interaction=nonstopmode -output-directory="build/unittest_stabilisatie.booklet" "build/unittest_stabilisatie.booklet/bookletify.latex"
|
||||
mv build/unittest_stabilisatie.booklet/bookletify.pdf pdf/unittest_stabilisatie.booklet.pdf
|
||||
|
||||
# pdf/unittest_stuursysteem.pdf: latex/unittest_stuursysteem.latex
|
||||
# cd build/unittest_stuursysteem && xelatex ../../latex/unittest_stuursysteem.latex
|
||||
# cd build/unittest_stuursysteem && xelatex ../../latex/unittest_stuursysteem.latex
|
||||
# cd build/unittest_stuursysteem && xelatex ../../latex/unittest_stuursysteem.latex
|
||||
# mv build/unittest_stuursysteem/unittest_stuursysteem.pdf pdf/unittest_stuursysteem.pdf
|
||||
|
||||
# pdf/unittest_stuursysteem.booklet.pdf: converters/bookletify.latex pdf/unittest_stuursysteem.pdf
|
||||
# mkdir -p build/unittest_stuursysteem.booklet
|
||||
# sed -e 's|?pdf?|../../pdf/unittest_stuursysteem.pdf|' converters/bookletify.latex >build/unittest_stuursysteem.booklet/bookletify.latex
|
||||
# pdflatex -interaction=nonstopmode -output-directory="build/unittest_stuursysteem.booklet" "build/unittest_stuursysteem.booklet/bookletify.latex"
|
||||
# mv build/unittest_stuursysteem.booklet/bookletify.pdf pdf/unittest_stuursysteem.booklet.pdf
|
||||
|
||||
pdf/projectdocument.pdf: latex/projectdocument.latex
|
||||
cd build/projectdocument && xelatex ../../latex/projectdocument.latex
|
||||
cd build/projectdocument && xelatex ../../latex/projectdocument.latex
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
---
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/pee51
|
||||
---
|
||||
|
||||
[parent](/tPb3Up1fQEuZ86yrJSkYRQ)
|
||||
|
||||
# Detailontwerp Stabilisatie
|
||||
|
||||
@ -142,8 +147,14 @@ Als $\omega = 0$ gelt $U = \frac{\tau}{K_T} R + U_{th}$ en $I = \frac{\tau}{K_T}
|
||||
Hiermee kan de volgende formule opgesteld worden
|
||||
|
||||
$$
|
||||
U=\frac{\omega}{K_v} + \frac{\tau}{K_T} R + R I_{noload} \\
|
||||
\Rightarrow RU=R\frac{\omega}{K_v} + R^2(\frac{\tau}{K_T} + I_{noload}) \\
|
||||
U = \frac{\omega}{K_v} + \frac{\tau}{K_T} R + R I_{noload}
|
||||
$$
|
||||
|
||||
$$
|
||||
\Rightarrow RU=R\frac{\omega}{K_v} + R^2(\frac{\tau}{K_T} + I_{noload})
|
||||
$$
|
||||
|
||||
$$
|
||||
\Rightarrow \sqrt{\frac{U}{\frac{\omega}{K_v} (\frac{\tau}{K_T} + I_{noload})}} = R
|
||||
$$
|
||||
|
||||
|
||||
@ -1,13 +1,30 @@
|
||||
---
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/pee51
|
||||
---
|
||||
|
||||
### Vehicle Control Unit
|
||||
[parent](/tPb3Up1fQEuZ86yrJSkYRQ)
|
||||
|
||||
De VCU is het belangrijkste onderdeel van het systeem, hiermee kunnen we het voertuig sturen, de belangrijkste keuze hierin is in welke taal we willen gaan programmeren. De reden hiervoor is zodat de volgende team makkelijker kan omgaan met de code. het makkelijkst is dan om met de Arduino IDE verder te gaan omdat het een bekent en veel gedocumenteerd systeem is. verder moet het ook draadloos verbinding kunnen maken met een controller zodat de volgende teams eventueel een andere keuze kunnen maken hoe ze willen sturen.
|
||||
|
||||
### Actuator
|
||||
## Vehicle Control unit
|
||||
|
||||
De VCU is een belangrijk onderdeel van het systeem, hiermee kunnen we het voertuig in een richting sturen en vooruit bewegen, de belangrijkste keuzes hierin zijn in welke taal we willen gaan programmeren en wat voor soort microcontroller we willen. De reden hiervoor is zodat de volgende team makkelijker kan omgaan met de code en het systeem makkelijker kunnen uitbreiden. het makkelijkst is dan om met de Arduino IDE en taal verder te gaan, omdat het een bekent en veel gedocumenteerd systeem is waar je veel over kan vinden op internet tegenover veel andere IDE's, programmeer talen en microcontrollers. verder moet het ook draadloos verbinding kunnen maken met een console controller zodat de volgende teams eventueel een andere keuze kunnen maken hoe ze willen sturen. Daarom hebben we voor de ESP32 gekozen omdat het alles aantikt met een gezond aantal GPIO pinnen.
|
||||
|
||||
## Actuator
|
||||
|
||||
De actuator hebben we nodig om de wielen in een richting te kunnen sturen volgens Max Kappert(student automotive engineer) hebben we de volgende parameters gekregen die we nodig hebben om het voertuig te kunnen sturen.
|
||||
|
||||

|
||||
| Parameter | Waarde | Eenheid | Opmerking |
|
||||
|--------------------------------|-------------|------------|----------------------|
|
||||
| Voertuigspanning | 12-14 | $V_DC$ | typisch voor auto-ECU's |
|
||||
| Stuurspanningdemperkle | 0-5 | $V_DC$ | naloge regeling |
|
||||
| PWM-signaal frequentie | 1000-3000 | $Hz$ | Typische range voor aansturing |
|
||||
| PWM duty cycle | 10-90 | $%$ | $0%$: minimale demping, $90%$: maximale demping |
|
||||
| Stroomverbruik klep | 0.5 - 2 | $A$ | Afhankelijk van de interne weerstand |
|
||||
| Wielsnelheid | 0-250 | $km/h$ | Meet snelheid per wiel |
|
||||
| Karrosserieversnelling | -3 tot +3 | $g$ | Laterale en verticale versnellingen |
|
||||
| Axiale potentiometer (veerweg) | 0- 50 | $mm$ | Meet veeruitslag |
|
||||
| Temperatuur werkbereik | -40 tot +85 | $^\circ C$ | Automobielstandaard |
|
||||
|
||||
Voor de Actuator is er een keuze gemaakt voor CDC (Continuous Damping Control) demper van SACHS, Maar vanwege de besteltijden van dit soort componenten kunnen we dit niet gebruiken. Daarom gebruiken we een actuator die er al staat, de A0-01/M van S-LINE. om de actuator te besturen gebruiken we een motordriver, de MDD20A. Dit is omdat we het al hebben en werkt met de huidige actuatoren en voldoende de parameters van de actuatoren behaald, daarom hebben we besloten om niet een nieuwe te kopen of te ontwerpen. Om ervoor te zorgen dat de actuatoren niet te ver gaan gebruiken we de AS5600 magnetic encoder. Dit is omdat de encoder een absoluut positie meegeeft en daarom voor minder problemen zorgt als het voertuig opnieuw opstart.
|
||||
|
||||
Voor de Actuator is er een keuze gemaakt voor CDC (Continuous Damping Control) demper van SACHS, Maar vanwege de besteltijden van dit soort componenten kunnen we dit niet gebruiken. Daarom gebruiken we een actuator die er al staat, de A0-01/M van S-LINE.
|
||||
|
||||
|
||||
@ -17,18 +17,19 @@ Deze onderdelen zijn gesplitst op basis van welke onderdelen die in dit project
|
||||
## Eis identificatie code
|
||||
|
||||
```
|
||||
REQ-X-X-X
|
||||
| | +- uniek identificatie nummer
|
||||
REQ-X-X[XX]
|
||||
| | |
|
||||
| | +- MH: zonder is het product niet bruikbaar
|
||||
| | SH: het product is zonder ook bruikbaar, maar is zeer gewenst
|
||||
| | CH: als het binnen de tijd lukt is het gewenst
|
||||
| | WH: niet gewenst
|
||||
| |
|
||||
| +--- A: algemeen
|
||||
| W: wiel assembly
|
||||
| S: stabilisatie
|
||||
| C: VCU
|
||||
| +--- uniek identificatie nummer
|
||||
|
|
||||
+----- M: zonder is het product niet bruikbaar
|
||||
S: het product is zonder ook bruikbaar, maar is zeer gewenst
|
||||
C: als het binnen de tijd lukt is het gewenst
|
||||
W: niet gewenst
|
||||
+----- A: algemeen
|
||||
W: wiel assembly
|
||||
S: stabilisatie
|
||||
C: VCU
|
||||
```
|
||||
|
||||
## Definities
|
||||
@ -38,62 +39,75 @@ REQ-X-X-X
|
||||
|
||||
## Algemene eisen
|
||||
|
||||
**REQ-M-A-1: Het voertuig exclusief bestuurder weegt 250 kilogram of minder.**
|
||||
**REQ-M-A-2: Het voertuig heeft een totale lengte van 4 meter of minder.**
|
||||
**REQ-M-A-3: Het voertuig heeft een totale breedte van 60 centimeter of minder.**
|
||||
**REQ-A-1[MH]: Het voertuig exclusief bestuurder weegt 250 kilogram of minder.**
|
||||
|
||||
**REQ-A-2[MH]: Het voertuig heeft een totale lengte van 4 meter of minder.**
|
||||
|
||||
**REQ-A-3[MH]: Het voertuig heeft een totale breedte van 60 centimeter of minder.**
|
||||
|
||||
> niet ietsje breeder?
|
||||
|
||||
**REQ-M-A-4: Het voertuig is ontworpen[^ontwerp] zodat die 60 kilometer per uur of sneller kan rijden.**
|
||||
**REQ-A-4[MH]: Het voertuig is ontworpen[^ontwerp] zodat de maximale snelheid 60 kilometer per uur of sneller is.**
|
||||
|
||||
> in welke omstandigheden.
|
||||
> in welke omstandigheden.
|
||||
|
||||
De 60 km/h is de minimale snelheid voor op de snelweg^[[https://www.rijksoverheid.nl/onderwerpen/wegen/vraag-en-antwoord/wat-is-de-minimumsnelheid-voor-het-wegverkeer](https://www.rijksoverheid.nl/onderwerpen/wegen/vraag-en-antwoord/wat-is-de-minimumsnelheid-voor-het-wegverkeer)].
|
||||
60 km/h is de minimale snelheid voor op de snelweg^[[https://www.rijksoverheid.nl/onderwerpen/wegen/vraag-en-antwoord/wat-is-de-minimumsnelheid-voor-het-wegverkeer](https://www.rijksoverheid.nl/onderwerpen/wegen/vraag-en-antwoord/wat-is-de-minimumsnelheid-voor-het-wegverkeer)].
|
||||
|
||||
**REQ-S-A-4: Het voertuig is ontworpen[^ontwerp] zodat die 150 kilometer per uur of sneller kan rijden in ideale omstandigheden[^omstandig].**
|
||||
**REQ-M-A-5: Het voertuig is ontworpen[^ontwerp] zodat die 100 kilometer actieradius of meer kan bereiken in ideale omstandigheden[^omstandig].**
|
||||
**REQ-A-5[SH]: Het voertuig is ontworpen[^ontwerp] zodat die 150 kilometer per uur of sneller kan rijden in ideale omstandigheden[^omstandig].**
|
||||
|
||||
**REQ-A-6[SH]: Het voertuig is ontworpen[^ontwerp] zodat die 100 kilometer actieradius of meer kan bereiken in ideale omstandigheden[^omstandig].**
|
||||
|
||||
De opdracht gever wil graag tussen Amsterdam van Rotterdam kunnen rijden.
|
||||
|
||||
**REQ-C-A-5: Het voertuig is ontworpen[^ontwerp] zodat die 250 kilometer actieradius of meer kan bereiken in ideale omstandigheden[^omstandig].**
|
||||
**REQ-A-7[CH]: Het voertuig is ontworpen[^ontwerp] zodat die 250 kilometer actieradius of meer kan bereiken in ideale omstandigheden[^omstandig].**
|
||||
|
||||
[^ontwerp]: Binnen de tijdspan van dit project is het niet mogelijk om op deze eisen te testen buiten een simulatie of rekenmodel.
|
||||
|
||||
[^omstandig]: De ideale omstandigheden is op een vlakke rechte geasfalteerde weg zonder wind, regen, hagel, sneeuw of andere weersomstandigheden die een negatief gevolg op de test kunnen hebben.
|
||||
|
||||
**REQ-C-A-6: Het voertuig is bestand tegen corrosie**
|
||||
**REQ-A-8[CH]: Het voertuig is bestand tegen corrosie**
|
||||
|
||||
**REQ-C-A-7: Het voertuig kan bedient worden door een bestuureder van 130 kilogram of minder.**
|
||||
**REQ-A-9[SH]: Het voertuig kan bedient worden door een bestuureder van 130 kilogram of minder.**
|
||||
|
||||
**REQ-M-A-8: Het voertuig kan bediend worden door een bestuurder met een lengte van 150 centimeter tot en met 200 centimeter.**
|
||||
**REQ-A-10[SH]: Het voertuig kan bediend worden door een bestuurder met een lengte van 150 centimeter tot en met 200 centimeter.**
|
||||
|
||||
> bron https://www.cbs.nl/nl-nl/maatwerk/2021/37/lichaamslengte
|
||||
> 8% van 19 jarige vrouwen zijn korter dan 160
|
||||
> 10.2% van 19 jarige mannen zijn korter dan 175
|
||||
|
||||
**REQ-M-A-9: De bestuurder van het voertuig zit volledig binnen de afmetingen van het voertuig, met uitzondering van de hoogte.**
|
||||
**REQ-S-A-10: Het zwaarte punt van het voertuig ligt 45 centimeter of minder boven de grond bij een vlakke grond.**
|
||||
**REQ-A-11[MH]: De bestuurder van het voertuig zit volledig binnen de afmetingen van het voertuig, met uitzondering van de hoogte.**
|
||||
|
||||
**REQ-A-12[SH]: Het zwaarte punt van het voertuig ligt 45 centimeter of minder boven de grond bij een vlakke grond.**
|
||||
|
||||
## Wiel Assembly
|
||||
|
||||
**REQ-M-W-1: het voertuig heeft twee wielen.**
|
||||
**REQ-M-W-2: het voertuig wordt aangedreven door beide wielen.**
|
||||
**REQ-S-W-3: het voertuig stuurt met beide wielen.**
|
||||
**REQ-M-W-4: het voertuig wordt aangedreven door elektromotoren.**
|
||||
**REQ-S-W-5: het voertuig kan remmen doormiddel van regenerative braking.**
|
||||
**REQ-S-W-6: de aandrijving bevindt zich in het wiel.**
|
||||
**REQ-M-W-7: het voertuig heeft een remvertraging van 6 meter per seconde per seconde of meer.**
|
||||
**REQ-M-W-8: het voertuig heeft een draaicirkel van 6 meter of minder.**
|
||||
**REQ-W-1[MH]: het voertuig heeft twee wielen.**
|
||||
|
||||
**REQ-W-2[MH]: het voertuig wordt aangedreven door beide wielen.**
|
||||
|
||||
**REQ-W-3[SH]: het voertuig stuurt met beide wielen.**
|
||||
|
||||
**REQ-W-4[MH]: het voertuig wordt aangedreven door elektromotoren.**
|
||||
|
||||
**REQ-W-5[SH]: het voertuig kan remmen doormiddel van regenerative braking.**
|
||||
|
||||
**REQ-W-6[SH]: de aandrijving bevindt zich in het wiel.**
|
||||
|
||||
**REQ-W-7[MH]: het voertuig heeft een remvertraging van 6 meter per seconde per seconde of meer.**
|
||||
|
||||
**REQ-W-8[MH]: het voertuig heeft een draaicirkel van 6 meter in diameter of minder.**
|
||||
|
||||
## Stabilisatie
|
||||
|
||||
**REQ-M-S-1: Het voertuig wordt actief gestabaliseert**
|
||||
**REQ-S-S-3: Het voertuig kan uit zichzelf weer recht komen te zitten vanaf een roll hoek van 5 graden**
|
||||
**REQ-S-1[MH]: Het voertuig wordt actief gestabaliseerd**
|
||||
|
||||
**REQ-S-2[SH]: Het voertuig kan uit zichzelf weer recht komen te zitten vanaf een roll hoek van 5 graden**
|
||||
|
||||
## VCU
|
||||
|
||||
**REQ-M-C-1: het voertuig wordt bestuurd door middel van een elektronische input, zoals een joystick, dat bedienbaar is door de bestuurder.**
|
||||
**REQ-M-C-2: er is een noodstop aanwezig.**
|
||||
**REQ-C-1[MH]: het voertuig wordt bestuurd doormiddel van een elektronisch input, zoals een joystick, die bedienbaar is door de bestuurder.**
|
||||
|
||||
**REQ-C-2[MH]: er is een noodstop aanwezig.**
|
||||
|
||||
> TODO: miss nog iets over wat die noodstop doet
|
||||
> hoe reageerd het stuur meganisme hierop
|
||||
|
||||
@ -103,7 +103,6 @@ De huidige status van het project vormt de basis voor verdere ontwikkelingen. De
|
||||
|
||||

|
||||
|
||||
|
||||
## Scope & Afbakening
|
||||
|
||||
### Scope
|
||||
|
||||
@ -1,7 +1,26 @@
|
||||
---
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/pee51
|
||||
---
|
||||
|
||||
[parent](/tPb3Up1fQEuZ86yrJSkYRQ)
|
||||
|
||||
# Superlight Persian Carier (SPC)
|
||||
|
||||
##
|
||||
## inhoudsopgaven
|
||||
|
||||
[toc]
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
## Stabilisatie
|
||||
|
||||
Voor de Stabilisatie is er een motor driver ontworpen. De specificaties van deze zijn groten deels gebaseerd op specefieke motor. Samen met Automotive is deze uitgekozen.
|
||||
|
||||
### De Motor
|
||||
|
||||
Het is een gevonden op Aliexpress, niet een heel erg betrowbare verkoper, maar we konnen niks anders geschikts vinden voor een redelijke prijs. Deze motor kan de kracht net niet aan continu, maar wel voor korte duur. De snelheid is wel ietse ingeperkt.
|
||||
|
||||
## bijlagen
|
||||
|
||||
|
||||
@ -1,152 +0,0 @@
|
||||
## Unit Testen Atabilisatie
|
||||
|
||||
### voedingen
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- 12V voeding
|
||||
|
||||
#### procedure
|
||||
|
||||
1. snel de voeding in op 12V met een stroom berensing van 50 mA
|
||||
2. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
3. meet de uitgangen van de twee voedingen, vul de tabel hieronder in
|
||||
|
||||
| | $5V$ | $12V$ |
|
||||
| -------- | ------:| -------:|
|
||||
| minimaal | $4.5V$ | $11.5V$ |
|
||||
| maximaal | $5.5V$ | $12.5V$ |
|
||||
| gemeeten | | |
|
||||
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### microcontroller
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- 12V voeding als de voedingen werken, anders met een 5V en 3.3v voeding
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
- ledje met bijhoren de weerstand voor 3.3V
|
||||
|
||||
#### procedure
|
||||
|
||||
1. sluit een ledje aan op een van de GPIO pinnen
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
3. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
4. sluit de USB kabel aan op de computer (dit is veilig omdat de USB alleen verbonden is met ground, de V+ is floating)
|
||||
5. upload een blinky voorbeeld progamma met de GPIO ingesteld van de led
|
||||
6. bekijk of het lidje knipperd
|
||||
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### half brug
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- als de microcontoller werkt:
|
||||
- 12V voeding als de voedingen werken, anders met een 5V en 3.3v voeding
|
||||
- 30V voor V Motor
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
- ocsiloscoop
|
||||
- zo niet:
|
||||
- 10V voor V motor
|
||||
- signaal generator met twee kanalen
|
||||
- ocsioscoop
|
||||
|
||||
#### procedure
|
||||
|
||||
1. sluit de ociloscoop aan op een van de uitgangen van de drijver (er komt 30V op te staan, beruik de juiste probe; geen juiste probe bij de hand, zelt de voeding voor V motor wa lager)
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
3. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
4. sluit de USB kabel aan op de computer (dit is veilig omdat de USB alleen verbonden is met ground, de V+ is floating)
|
||||
5. upload een test progamma die de PWM aansuurt voor de FET's
|
||||
- de PWM per half bridge zijn aangesloten op de a en b uitganen van 1 timer per half brug. zorg dat een van de uitput geinverteerd is en de twee vergeleijk waardes zo zijn zodat er een korte dead time is. ze mogen nooit tegerlijk hoog zijn!
|
||||
6. bekijk het signaal op de osciloscoop
|
||||
7. herhaal de test voor alle drie de half bruggen
|
||||
|
||||
resultaat:
|
||||
|
||||
- brug a:
|
||||
- brug b:
|
||||
- brug c:
|
||||
|
||||
opmerkingen:
|
||||
|
||||
### IMU
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- een microcontroller met I2C (kan de motoro driver zelf zijn)
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
|
||||
#### procedure
|
||||
|
||||
1. sluit de IMU aan op de motor driver
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
3. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
4. sluit de USB kabel aan op de computer (dit is veilig omdat de USB alleen verbonden is met ground, de V+ is floating)
|
||||
5. upload een blinky voorbeeld progamma met de GPIO ingesteld van de led
|
||||
6. bekijk de serial plotter terwel je de IMU draait.
|
||||
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### stroom meting
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- 12V voeding (of 5V bij beperking van beschikbaare voedingen)
|
||||
- voeding die 50A kan leveren (of zoveel mogenlijk) voor V motor
|
||||
- bij voorkeur een load die de $50A_{DC}$ kan op nemen, ander kan de uitgang korgesloten worden als de voeding dat toestaat.
|
||||
- multimeter
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
|
||||
#### procedure
|
||||
|
||||
1. sluit de load aan op deen van de uitgangen van de motor driver
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
3. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
4. sluit de USB kabel aan op de computer (dit is veilig omdat de USB alleen verbonden is met ground, de V+ is floating)
|
||||
5. upload een programma die alle high side fet's dicht zet en de low side fet's open
|
||||
6. sluit de voeding voor V motor aan
|
||||
7. meet uitgang van de stroom meeting
|
||||
8. zet de v motor voeding uit en verlaats de load naar een andere uitgang
|
||||
9. zet de voeding weer aan en meet de stoom meting
|
||||
10. herhaal dit voor de laaste uitgang
|
||||
|
||||
TODO: add meet table
|
||||
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### encoder
|
||||
|
||||
#### benodigdheden
|
||||
|
||||
- een microcontroller met I2C (kan de motoro driver zelf zijn)
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
|
||||
#### procedure
|
||||
|
||||
1. sluit de Encoder aan op de motor driver
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
3. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
4. sluit de USB kabel aan op de computer (dit is veilig omdat de USB alleen verbonden is met ground, de V+ is floating)
|
||||
5. upload een voorbeeld progamma voor de encoder.
|
||||
6. bekijk de serial plotter terwel je de magneer van de encoder draait
|
||||
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
---
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/pee51
|
||||
---
|
||||
|
||||
## testen
|
||||
[parent](/tPb3Up1fQEuZ86yrJSkYRQ)
|
||||
|
||||
### voedingen
|
||||
## Unit Testen Stabilisatie
|
||||
|
||||
#### benodigdheden
|
||||
### Voedingen
|
||||
|
||||
#### Benodigdheden
|
||||
|
||||
- 12V voeding
|
||||
|
||||
#### procedure
|
||||
#### Procedure
|
||||
|
||||
1. snel de voeding in op 12V met een stroom berensing van 50 mA
|
||||
2. sluit de 12V voeding aan op de 12V en GND ingnangen op de driver
|
||||
@ -23,16 +28,16 @@ Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### microcontroller
|
||||
### Microcontroller
|
||||
|
||||
#### benodigdheden
|
||||
#### Benodigdheden
|
||||
|
||||
- 12V voeding als de voedingen werken, anders met een 5V en 3.3v voeding
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- USB B kabel naar de computer
|
||||
- ledje met bijhoren de weerstand voor 3.3V
|
||||
|
||||
#### procedure
|
||||
#### Procedure
|
||||
|
||||
1. sluit een ledje aan op een van de GPIO pinnen
|
||||
2. snel de voeding in op 12V met een stroom berensing van 150 mA
|
||||
@ -45,9 +50,9 @@ Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
### half brug
|
||||
### Half-brug
|
||||
|
||||
#### benodigdheden
|
||||
#### Benodigdheden
|
||||
|
||||
- als de microcontoller werkt:
|
||||
- 12V voeding als de voedingen werken, anders met een 5V en 3.3v voeding
|
||||
@ -150,3 +155,4 @@ opmergingen:
|
||||
Geslaagd:
|
||||
|
||||
opmergingen:
|
||||
|
||||
|
||||
50
markdown/unittest_stuursysteem.md
Normal file
50
markdown/unittest_stuursysteem.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/pee51
|
||||
---
|
||||
|
||||
[parent](/tPb3Up1fQEuZ86yrJSkYRQ)
|
||||
|
||||
# unit testen Stuur systeem
|
||||
|
||||
## unit test controller
|
||||
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- een USB-C kabel aangesloten van de microcontroller naar een computer
|
||||
- een controller om het voertuig mee te besturen
|
||||
|
||||
1. Upload het programma naar de esp32
|
||||
2. pair de controller via bluetooth met de esp32
|
||||
3. check voor de waardes op je computer
|
||||
4. druk knoppen in en beweeg joysticks
|
||||
5. kijk of er waardes binnenkomen.
|
||||
|
||||
de test is geslaagd wanneer alle knoppen consistent een waarde terug kunnen sturen naar de terminal van de Arduino IDE
|
||||
|
||||
|
||||
## unit test Actuator
|
||||
|
||||
- voeding die minimaal 24 volt aankan
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- een USB-C kabel aangesloten van de microcontroller naar een computer
|
||||
- een controller om het voertuig mee te besturen
|
||||
|
||||
1. sluit de voeding aan op de motorcontroller met 24 volt en een stroombegrensing van 2A
|
||||
2. verbind de PWM en DIR pinnen tussen de eps32 en motorcontroller
|
||||
3. pair de controller met de esp32
|
||||
4. beweeg de linker joystick van links naar rechts.
|
||||
5. check de reactie van het wiel
|
||||
|
||||
de test is geslaagd wanneer de controller het wiel links en rechts kan draaien en het wiel stopt in de aangegeven richting en niet te zijn eigen grens overschrijt.
|
||||
|
||||
## integratie test VCU
|
||||
|
||||
- computer met Arduino IDE geinstaleerd
|
||||
- een USB-C kabel aangesloten van de microcontroller naar een computer
|
||||
- een controller om het voertuig mee te besturen
|
||||
|
||||
1. sluit de de motor en de stabilisatie units met de VCU
|
||||
2. pair de controller met de esp32
|
||||
3. beweeg de rechter joystick omhoog en omlaag
|
||||
4. check de reactie met het wiel en de stabilisator
|
||||
|
||||
de test is geslaagd wanneer de controller de motor kan aansturen en de stabilisatie zijn vermogen kan varieren gebaseerd op het wiel
|
||||
Loading…
x
Reference in New Issue
Block a user