diff --git a/.gitmodules b/.gitmodules index 79209740..4e72920d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -121,9 +121,9 @@ [submodule "vendor/grammars/Handlebars"] path = vendor/grammars/Handlebars url = https://github.com/daaain/Handlebars -[submodule "vendor/grammars/powershell.tmbundle"] - path = vendor/grammars/powershell.tmbundle - url = https://github.com/davidpeckham/powershell.tmbundle +[submodule "vendor/grammars/powershell"] + path = vendor/grammars/powershell + url = https://github.com/SublimeText/PowerShell [submodule "vendor/grammars/jade-tmbundle"] path = vendor/grammars/jade-tmbundle url = https://github.com/davidrios/jade-tmbundle @@ -337,6 +337,9 @@ [submodule "vendor/grammars/ini.tmbundle"] path = vendor/grammars/ini.tmbundle url = https://github.com/textmate/ini.tmbundle +[submodule "vendor/grammars/desktop.tmbundle"] + path = vendor/grammars/desktop.tmbundle + url = https://github.com/Mailaender/desktop.tmbundle.git [submodule "vendor/grammars/io.tmbundle"] path = vendor/grammars/io.tmbundle url = https://github.com/textmate/io.tmbundle @@ -525,9 +528,6 @@ [submodule "vendor/grammars/sublime-bsv"] path = vendor/grammars/sublime-bsv url = https://github.com/thotypous/sublime-bsv -[submodule "vendor/grammars/AutoHotkey"] - path = vendor/grammars/AutoHotkey - url = https://github.com/robertcollier4/AutoHotkey [submodule "vendor/grammars/Sublime-HTTP"] path = vendor/grammars/Sublime-HTTP url = https://github.com/httpspec/sublime-highlighting @@ -549,3 +549,48 @@ [submodule "vendor/grammars/turtle.tmbundle"] path = vendor/grammars/turtle.tmbundle url = https://github.com/peta/turtle.tmbundle +[submodule "vendor/grammars/liquid.tmbundle"] + path = vendor/grammars/liquid.tmbundle + url = https://github.com/bastilian/validcode-textmate-bundles +[submodule "vendor/grammars/ats.sublime"] + path = vendor/grammars/ats.sublime + url = https://github.com/steinwaywhw/ats-mode-sublimetext +[submodule "vendor/grammars/Modelica"] + path = vendor/grammars/Modelica + url = https://github.com/BorisChumichev/modelicaSublimeTextPackage +[submodule "vendor/grammars/sublime-apl"] + path = vendor/grammars/sublime-apl + url = https://github.com/StoneCypher/sublime-apl +[submodule "vendor/grammars/CLIPS-sublime"] + path = vendor/grammars/CLIPS-sublime + url = https://github.com/psicomante/CLIPS-sublime +[submodule "vendor/grammars/Creole"] + path = vendor/grammars/Creole + url = https://github.com/Siddley/Creole +[submodule "vendor/grammars/GDScript-sublime"] + path = vendor/grammars/GDScript-sublime + url = https://github.com/beefsack/GDScript-sublime +[submodule "vendor/grammars/sublime-golo"] + path = vendor/grammars/sublime-golo + url = https://github.com/TypeUnsafe/sublime-golo +[submodule "vendor/grammars/JSyntax"] + path = vendor/grammars/JSyntax + url = https://github.com/bcj/JSyntax +[submodule "vendor/grammars/TXL"] + path = vendor/grammars/TXL + url = https://github.com/MikeHoffert/Sublime-Text-TXL-syntax +[submodule "vendor/grammars/G-Code"] + path = vendor/grammars/G-Code + url = https://github.com/robotmaster/sublime-text-syntax-highlighting +[submodule "vendor/grammars/grace-tmbundle"] + path = vendor/grammars/grace-tmbundle + url = https://github.com/zmthy/grace-tmbundle +[submodule "vendor/grammars/sublime-text-ox"] + path = vendor/grammars/sublime-text-ox + url = https://github.com/andreashetland/sublime-text-ox +[submodule "vendor/grammars/AutoHotkey"] + path = vendor/grammars/AutoHotkey + url = https://github.com/ahkscript/SublimeAutoHotkey +[submodule "vendor/grammars/ec.tmbundle"] + path = vendor/grammars/ec.tmbundle + url = https://github.com/ecere/ec.tmbundle diff --git a/LICENSE b/LICENSE index f09a7d0a..c0a52444 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2014 GitHub, Inc. +Copyright (c) 2011-2015 GitHub, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index e711c659..215aaf52 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,11 @@ The Language stats bar is built by aggregating the languages of each file in tha ## Overrides -Linguist supports custom overrides for language definitions and vendored paths. Please note that the overrides currently only affect the language statistics for a repository and not the syntax-highlighting of files. +Linguist supports a number of different custom overrides strategies for language definitions and vendored paths. -Commit a `.gitattributes` file to your project and use standard git-style path matchers for the files you want to override to set `linguist-language` and `linguist-vendored`. +### Using gitattributes + +Add a `.gitattributes` file to your project and use standard git-style path matchers for the files you want to override to set `linguist-language` and `linguist-vendored`. ``` $ cat .gitattributes @@ -40,3 +42,16 @@ $ cat .gitattributes special-vendored-path/* linguist-vendored jquery.js linguist-vendored=false ``` + +### Using Emacs and Vim modelines + +Alternatively, you can use Vim and Emacs style modelines to set the language for a single file. Modelines can be placed anywhere within a file and are respected when determining how to syntax-highlight a file on GitHub.com + +``` +Vim +vim: set filetype=prolog: +vim: set ft=cpp: + +Emacs +-*- mode: php;-*- +``` diff --git a/grammars.yml b/grammars.yml index c85b2de6..00f2c9b1 100644 --- a/grammars.yml +++ b/grammars.yml @@ -24,17 +24,29 @@ vendor/grammars/Agda.tmbundle: - source.agda vendor/grammars/Alloy.tmbundle: - source.alloy -vendor/grammars/AutoHotkey: +vendor/grammars/AutoHotkey/: - source.ahk +vendor/grammars/CLIPS-sublime: +- source.clips vendor/grammars/ColdFusion: - source.cfscript - source.cfscript.cfc - text.cfml.basic - text.html.cfm +vendor/grammars/Creole: +- text.html.creole vendor/grammars/Docker.tmbundle: - source.dockerfile vendor/grammars/Elm.tmLanguage: - source.elm +vendor/grammars/G-Code/: +- source.LS +- source.MCPOST +- source.MOD +- source.apt +- source.gcode +vendor/grammars/GDScript-sublime/: +- source.gdscript vendor/grammars/Handlebars: - text.html.handlebars vendor/grammars/IDL-Syntax: @@ -42,10 +54,14 @@ vendor/grammars/IDL-Syntax: vendor/grammars/Isabelle.tmbundle: - source.isabelle.root - source.isabelle.theory +vendor/grammars/JSyntax/: +- source.j vendor/grammars/Julia.tmbundle: - source.julia vendor/grammars/LiveScript.tmbundle: - source.livescript +vendor/grammars/Modelica/: +- source.modelica vendor/grammars/NSIS: - source.nsis vendor/grammars/NimLime: @@ -96,6 +112,8 @@ vendor/grammars/SublimeBrainfuck: - source.bf vendor/grammars/SublimeXtend: - source.xtend +vendor/grammars/TXL/: +- source.txl vendor/grammars/Textmate-Gosu-Bundle: - source.gosu.2 vendor/grammars/VBDotNetSyntax: @@ -128,6 +146,8 @@ vendor/grammars/assembly.tmbundle: vendor/grammars/atom-salt: - source.python.salt - source.yaml.salt +vendor/grammars/ats.sublime: +- source.ats vendor/grammars/autoitv3-tmbundle: - source.autoit.3 vendor/grammars/awk-sublime: @@ -170,6 +190,8 @@ vendor/grammars/dart-sublime-bundle: - source.dart - source.pubspec - text.dart-doccomments +vendor/grammars/desktop.tmbundle: +- source.desktop vendor/grammars/diff.tmbundle: - source.diff vendor/grammars/dylan.tmbundle: @@ -178,6 +200,8 @@ vendor/grammars/dylan.tmbundle: - source.makegen vendor/grammars/ebundles/Bundles/MSDOS batch file.tmbundle: - source.dosbatch +vendor/grammars/ec.tmbundle/: +- source.c.ec vendor/grammars/eiffel.tmbundle: - source.eiffel vendor/grammars/elixir-tmbundle: @@ -205,6 +229,8 @@ vendor/grammars/gnuplot-tmbundle: - source.gnuplot vendor/grammars/go-tmbundle: - source.go +vendor/grammars/grace-tmbundle/: +- source.grace vendor/grammars/gradle.tmbundle: - source.groovy.gradle vendor/grammars/graphviz.tmbundle: @@ -289,6 +315,8 @@ vendor/grammars/less.tmbundle: - source.css.less vendor/grammars/lilypond.tmbundle: - source.lilypond +vendor/grammars/liquid.tmbundle: +- text.html.liquid vendor/grammars/lisp.tmbundle: - source.lisp vendor/grammars/llvm.tmbundle: @@ -348,7 +376,7 @@ vendor/grammars/pike-textmate: - source.pike vendor/grammars/postscript.tmbundle: - source.postscript -vendor/grammars/powershell.tmbundle: +vendor/grammars/powershell: - source.powershell vendor/grammars/processing.tmbundle: - source.processing @@ -400,6 +428,8 @@ vendor/grammars/standard-ml.tmbundle: - source.ml vendor/grammars/sublime-MuPAD: - source.mupad +vendor/grammars/sublime-apl/: +- source.apl vendor/grammars/sublime-befunge: - source.befunge vendor/grammars/sublime-better-typescript: @@ -411,6 +441,8 @@ vendor/grammars/sublime-cirru: vendor/grammars/sublime-glsl: - source.essl - source.glsl +vendor/grammars/sublime-golo/: +- source.golo vendor/grammars/sublime-idris: - source.idris vendor/grammars/sublime-mask: @@ -427,6 +459,8 @@ vendor/grammars/sublime-sourcepawn: - source.sp vendor/grammars/sublime-tea: - source.tea +vendor/grammars/sublime-text-ox/: +- source.ox vendor/grammars/sublime_cobol: - source.acucobol - source.cobol diff --git a/lib/linguist/blob_helper.rb b/lib/linguist/blob_helper.rb index 07e1ee52..c368b4d0 100644 --- a/lib/linguist/blob_helper.rb +++ b/lib/linguist/blob_helper.rb @@ -99,7 +99,7 @@ module Linguist elsif name.nil? "attachment" else - "attachment; filename=#{EscapeUtils.escape_url(name)}" + "attachment; filename=#{EscapeUtils.escape_url(File.basename(name))}" end end @@ -233,7 +233,7 @@ module Linguist # # Return true or false def vendored? - path =~ VendoredRegexp ? true : false + name =~ VendoredRegexp ? true : false end # Public: Get each line of data @@ -301,7 +301,7 @@ module Linguist # # Return true or false def generated? - @_generated ||= Generated.generated?(path, lambda { data }) + @_generated ||= Generated.generated?(name, lambda { data }) end # Public: Detects the Language of the blob. diff --git a/lib/linguist/file_blob.rb b/lib/linguist/file_blob.rb index 2ca74c2d..04441935 100644 --- a/lib/linguist/file_blob.rb +++ b/lib/linguist/file_blob.rb @@ -3,7 +3,7 @@ require 'linguist/blob_helper' module Linguist # A FileBlob is a wrapper around a File object to make it quack # like a Grit::Blob. It provides the basic interface: `name`, - # `data`, `path` and `size`. + # `data`, and `size`. class FileBlob include BlobHelper @@ -14,50 +14,43 @@ module Linguist # # Returns a FileBlob. def initialize(path, base_path = nil) - @fullpath = path - @path = base_path ? path.sub("#{base_path}/", '') : path + @path = path + @name = base_path ? path.sub("#{base_path}/", '') : path end # Public: Filename # # Examples # - # FileBlob.new("/path/to/linguist/lib/linguist.rb").path + # FileBlob.new("/path/to/linguist/lib/linguist.rb").name # # => "/path/to/linguist/lib/linguist.rb" # # FileBlob.new("/path/to/linguist/lib/linguist.rb", - # "/path/to/linguist").path + # "/path/to/linguist").name # # => "lib/linguist.rb" # # Returns a String - attr_reader :path + attr_reader :name # Public: Read file permissions # # Returns a String like '100644' def mode - File.stat(@fullpath).mode.to_s(8) - end - - # Public: File name - # - # Returns a String - def name - File.basename(@fullpath) + File.stat(@path).mode.to_s(8) end # Public: Read file contents. # # Returns a String. def data - File.read(@fullpath) + File.read(@path) end # Public: Get byte size # # Returns an Integer. def size - File.size(@fullpath) + File.size(@path) end # Public: Get file extension. @@ -74,7 +67,7 @@ module Linguist # # Returns an Array def extensions - basename, *segments = name.split(".") + basename, *segments = File.basename(name).split(".") segments.map.with_index do |segment, index| "." + segments[index..-1].join(".") diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb index 5e603f23..ee1a3625 100644 --- a/lib/linguist/heuristics.rb +++ b/lib/linguist/heuristics.rb @@ -61,6 +61,9 @@ module Linguist @heuristic.call(data) end + # Common heuristics + ObjectiveCRegex = /^[ \t]*@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/ + disambiguate "BitBake", "BlitzBasic" do |data| if /^\s*; /.match(data) || data.include?("End Function") Language["BlitzBasic"] @@ -69,8 +72,16 @@ module Linguist end end + disambiguate "C#", "Smalltalk" do |data| + if /![\w\s]+methodsFor: /.match(data) + Language["Smalltalk"] + elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data) + Language["C#"] + end + end + disambiguate "Objective-C", "C++", "C" do |data| - if (/^[ \t]*@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/.match(data)) + if ObjectiveCRegex.match(data) Language["Objective-C"] elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) || /^\s*template\s* ")) + Language["GAP"] + # Heads up - we don't usually write heuristics like this (with no regex match) + else + Language["Scilab"] + end + end + disambiguate "Common Lisp", "OpenCL", "Cool" do |data| if data.include?("(defun ") Language["Common Lisp"] @@ -152,6 +172,20 @@ module Linguist end end + disambiguate "M", "Mathematica", "Matlab", "Mercury", "Objective-C" do |data| + if ObjectiveCRegex.match(data) + Language["Objective-C"] + elsif data.include?(":- module") + Language["Mercury"] + elsif /^\s*;/.match(data) + Language["M"] + elsif /^\s*\(\*/.match(data) + Language["Mathematica"] + elsif /^\s*%/.match(data) + Language["Matlab"] + end + end + disambiguate "Gosu", "JavaScript" do |data| Language["Gosu"] if /^uses java\./.match(data) end @@ -164,6 +198,14 @@ module Linguist end end + disambiguate "Common Lisp", "NewLisp" do |data| + if /^\s*\((defun|in-package|defpackage) /.match(data) + Language["Common Lisp"] + elsif /^\s*\(define /.match(data) + Language["NewLisp"] + end + end + disambiguate "TypeScript", "XML" do |data| if data.include?(" # # - # Returns the Lexer or nil if none was found. + # Returns the Language or nil if none was found. def self.find_by_alias(name) name && @alias_index[name.downcase] end @@ -219,7 +221,7 @@ module Linguist end - # Public: Look up Language by its name or lexer. + # Public: Look up Language by its name. # # name - The String name of the Language # @@ -243,7 +245,7 @@ module Linguist # # This list is configured in "popular.yml". # - # Returns an Array of Lexers. + # Returns an Array of Languages. def self.popular @popular ||= all.select(&:popular?).sort_by { |lang| lang.name.downcase } end @@ -255,7 +257,7 @@ module Linguist # # This list is created from all the languages not listed in "popular.yml". # - # Returns an Array of Lexers. + # Returns an Array of Languages. def self.unpopular @unpopular ||= all.select(&:unpopular?).sort_by { |lang| lang.name.downcase } end @@ -375,11 +377,6 @@ module Linguist # Returns the name String attr_reader :search_term - # Public: Get Lexer - # - # Returns the Lexer - attr_reader :lexer - # Public: Get the name of a TextMate-compatible scope # # Returns the scope @@ -495,16 +492,6 @@ module Linguist @searchable end - # Public: Highlight syntax of text - # - # text - String of code to be highlighted - # options - A Hash of options (defaults to {}) - # - # Returns html String - def colorize(text, options = {}) - lexer.highlight(text, options) - end - # Public: Return name as String representation def to_s name @@ -580,7 +567,6 @@ module Linguist :color => options['color'], :type => options['type'], :aliases => options['aliases'], - :lexer => options['lexer'], :tm_scope => options['tm_scope'], :ace_mode => options['ace_mode'], :wrap => options['wrap'], diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index e1b494a6..e899046e 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -54,13 +54,14 @@ APL: extensions: - .apl - .dyalog - tm_scope: none + tm_scope: source.apl ace_mode: text ASP: type: programming color: "#6a40fd" search_term: aspx-vb + tm_scope: text.html.asp aliases: - aspx - aspx-vb @@ -81,10 +82,9 @@ ATS: - ats2 extensions: - .dats - - .atxt - .hats - .sats - tm_scope: source.ocaml + tm_scope: source.ats ace_mode: ocaml ActionScript: @@ -381,6 +381,7 @@ C++: - .cpp - .c++ - .cc + - .cp - .cxx - .h - .h++ @@ -413,7 +414,7 @@ CLIPS: type: programming extensions: - .clp - tm_scope: none + tm_scope: source.clips ace_mode: text CMake: @@ -504,10 +505,10 @@ Clojure: - .cl2 - .cljc - .cljs + - .cljs.hl - .cljscm - .cljx - .hic - - .hl filenames: - riemann.config @@ -622,7 +623,7 @@ Creole: wrap: true extensions: - .creole - tm_scope: none + tm_scope: text.html.creole ace_mode: text Crystal: @@ -811,9 +812,11 @@ Emacs Lisp: - emacs filenames: - .emacs + - .emacs.desktop extensions: - .el - .emacs + - .emacs.desktop ace_mode: lisp EmberScript: @@ -915,6 +918,7 @@ Forth: color: "#341708" extensions: - .fth + - .4TH - .4th - .F - .f @@ -939,7 +943,7 @@ G-code: - .g - .gco - .gcode - tm_scope: none + tm_scope: source.gcode ace_mode: gcode GAMS: @@ -956,6 +960,7 @@ GAP: - .gap - .gd - .gi + - .tst tm_scope: none ace_mode: text @@ -972,7 +977,7 @@ GDScript: type: programming extensions: - .gd - tm_scope: none + tm_scope: source.gdscript ace_mode: text GLSL: @@ -1070,7 +1075,7 @@ Golo: color: "#f6a51f" extensions: - .golo - tm_scope: none + tm_scope: source.golo ace_mode: text Gosu: @@ -1088,7 +1093,7 @@ Grace: type: programming extensions: - .grace - tm_scope: none + tm_scope: source.grace ace_mode: text Gradle: @@ -1172,6 +1177,7 @@ HTML: extensions: - .html - .htm + - .html.hl - .st - .xht - .xhtml @@ -1197,7 +1203,7 @@ HTML+ERB: - erb extensions: - .erb - - .deface + - .erb.deface ace_mode: html_ruby HTML+PHP: @@ -1228,13 +1234,14 @@ Haml: type: markup extensions: - .haml - - .deface + - .haml.deface ace_mode: haml Handlebars: type: markup aliases: - hbs + - htmlbars extensions: - .handlebars - .hbs @@ -1370,7 +1377,7 @@ J: type: programming extensions: - .ijs - tm_scope: none + tm_scope: source.j ace_mode: text JSON: @@ -1595,7 +1602,7 @@ Liquid: type: markup extensions: - .liquid - tm_scope: none + tm_scope: text.html.liquid ace_mode: liquid Literate Agda: @@ -1834,6 +1841,13 @@ Mirah: tm_scope: source.ruby ace_mode: ruby +Modelica: + type: programming + extensions: + - .mo + tm_scope: source.modelica + ace_mode: text + Monkey: type: programming extensions: @@ -1882,6 +1896,19 @@ NetLogo: tm_scope: source.lisp ace_mode: lisp +NewLisp: + type: programming + lexer: NewLisp + color: "#eedd66" + extensions: + - .nl + - .lisp + - .lsp + interpreters: + - newlisp + tm_scope: source.lisp + ace_mode: lisp + Nginx: type: markup extensions: @@ -2054,7 +2081,7 @@ OpenSCAD: extensions: - .scad tm_scope: none - ace_mode: text + ace_mode: scad Org: type: prose @@ -2070,7 +2097,7 @@ Ox: - .ox - .oxh - .oxo - tm_scope: none + tm_scope: source.ox ace_mode: text Oxygene: @@ -2211,6 +2238,8 @@ Perl6: - .pm - .pm6 - .t + filenames: + - Rexfile interpreters: - perl6 tm_scope: none @@ -2376,6 +2405,8 @@ Python: - python - python2 - python3 + aliases: + - rusthon Python traceback: type: data @@ -2423,7 +2454,6 @@ R: RAML: type: data - lexer: YAML ace_mode: yaml tm_scope: source.yaml color: "#77d9fb" @@ -2650,8 +2680,8 @@ STON: group: Smalltalk extensions: - .ston - tm_scope: source.json - ace_mode: lisp + tm_scope: source.smalltalk + ace_mode: text Sage: type: programming @@ -2892,7 +2922,7 @@ TXL: type: programming extensions: - .txl - tm_scope: none + tm_scope: source.txl ace_mode: text Tcl: @@ -3288,13 +3318,21 @@ Zimpl: tm_scope: none ace_mode: text +desktop: + type: data + extensions: + - .desktop + - .desktop.in + tm_scope: source.desktop + ace_mode: text + eC: type: programming search_term: ec extensions: - .ec - .eh - tm_scope: none + tm_scope: source.c.ec ace_mode: text edn: diff --git a/lib/linguist/lazy_blob.rb b/lib/linguist/lazy_blob.rb index ab6c4bee..9691bca5 100644 --- a/lib/linguist/lazy_blob.rb +++ b/lib/linguist/lazy_blob.rb @@ -14,15 +14,13 @@ module Linguist attr_reader :repository attr_reader :oid - attr_reader :path + attr_reader :name attr_reader :mode - alias :name :path - - def initialize(repo, oid, path, mode = nil) + def initialize(repo, oid, name, mode = nil) @repository = repo @oid = oid - @path = path + @name = name @mode = mode end diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb new file mode 100644 index 00000000..e77597f4 --- /dev/null +++ b/lib/linguist/strategy/modeline.rb @@ -0,0 +1,30 @@ +module Linguist + module Strategy + class Modeline + EmacsModeline = /-\*-\s*mode:\s*(\w+);?\s*-\*-/i + VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\//i + + # Public: Detects language based on Vim and Emacs modelines + # + # blob - An object that quacks like a blob. + # + # Examples + # + # Modeline.call(FileBlob.new("path/to/file")) + # + # Returns an Array with one Language if the blob has a Vim or Emacs modeline + # that matches a Language name or alias. Returns an empty array if no match. + def self.call(blob, _ = nil) + Array(Language.find_by_alias(modeline(blob.data))) + end + + # Public: Get the modeline from the first n-lines of the file + # + # Returns a String or nil + def self.modeline(data) + match = data.match(EmacsModeline) || data.match(VimModeline) + match[1] if match + end + end + end +end diff --git a/lib/linguist/tokenizer.rb b/lib/linguist/tokenizer.rb index 4b2ea607..05882649 100644 --- a/lib/linguist/tokenizer.rb +++ b/lib/linguist/tokenizer.rb @@ -33,7 +33,8 @@ module Linguist [''], # XML ['{-', '-}'], # Haskell ['(*', '*)'], # Coq - ['"""', '"""'] # Python + ['"""', '"""'], # Python + ["'''", "'''"] # Python ] START_SINGLE_LINE_COMMENT = Regexp.compile(SINGLE_LINE_COMMENTS.map { |c| diff --git a/lib/linguist/vendor.yml b/lib/linguist/vendor.yml index 4ba241ca..9f6b401b 100644 --- a/lib/linguist/vendor.yml +++ b/lib/linguist/vendor.yml @@ -40,7 +40,7 @@ # Minified JavaScript and CSS - (\.|-)min\.(js|css)$ -#Stylesheets imported from packages +# Stylesheets imported from packages - ([^\s]*)import\.(css|less|scss|styl)$ # Bootstrap css and js diff --git a/lib/linguist/version.rb b/lib/linguist/version.rb index 3f330f79..e8c4f98b 100644 --- a/lib/linguist/version.rb +++ b/lib/linguist/version.rb @@ -1,3 +1,3 @@ module Linguist - VERSION = "4.2.6" + VERSION = "4.3.1" end diff --git a/samples/ATS/main.atxt b/samples/ATS/main.atxt deleted file mode 100644 index 3bba35f0..00000000 --- a/samples/ATS/main.atxt +++ /dev/null @@ -1,215 +0,0 @@ -%{ -#include "./../ATEXT/atextfun.hats" -%} - - - - - - -EFFECTIVATS-DiningPhil2 -#patscode_style() - - - - -

-Effective ATS: Dining Philosophers -

- -In this article, I present an implementation of a slight variant of the -famous problem of 5-Dining-Philosophers by Dijkstra that makes simple but -convincing use of linear types. - -

-The Original Problem -

- -There are five philosophers sitting around a table and there are also 5 -forks placed on the table such that each fork is located between the left -hand of a philosopher and the right hand of another philosopher. Each -philosopher does the following routine repeatedly: thinking and dining. In -order to dine, a philosopher needs to first acquire two forks: one located -on his left-hand side and the other on his right-hand side. After -finishing dining, a philosopher puts the two acquired forks onto the table: -one on his left-hand side and the other on his right-hand side. - -

-A Variant of the Original Problem -

- -The following twist is added to the original version: - -

- -After a fork is used, it becomes a "dirty" fork and needs to be put in a -tray for dirty forks. There is a cleaner who cleans dirty forks and then -puts them back on the table. - -

-Channels for Communication -

- -A channel is just a shared queue of fixed capacity. The following two -functions are for inserting an element into and taking an element out of a -given channel: - -
-#pats2xhtml_sats("\
-fun{a:vt0p} channel_insert (channel (a), a): void
-fun{a:vt0p} channel_takeout (chan: channel (a)): (a) 
-")
- -If [channel_insert] is called on a channel that is full, then the caller is -blocked until an element is taken out of the channel. If [channel_takeout] -is called on a channel that is empty, then the caller is blocked until an -element is inserted into the channel. - -

-A Channel for Each Fork -

- -Forks are resources given a linear type. Each fork is initially stored in a -channel, which can be obtained by calling the following function: - -
-#pats2xhtml_sats("\
-fun fork_changet (n: nphil): channel(fork)
-")
- -where the type [nphil] is defined to be [natLt(5)] (for natural numbers -less than 5). The channels for storing forks are chosen to be of capacity -2. The reason that channels of capacity 2 are chosen to store at most one -element (in each of them) is to guarantee that these channels can never be -full (so that there is no attempt made to send signals to awake callers -supposedly being blocked due to channels being full). - - -

-A Channel for the Fork Tray -

- -A tray for storing "dirty" forks is also a channel, which can be obtained -by calling the following function: - -
-#pats2xhtml_sats("\
-fun forktray_changet ((*void*)): channel(fork)
-")
- -The capacity chosen for the channel is 6 (instead of 5) so that it can -never become full (as there are only 5 forks in total). - -

-Philosopher Loop -

- -Each philosopher is implemented as a loop: - -
-#pats2xhtml_dats('\
-implement
-phil_loop (n) = let
-//
-val () = phil_think (n)
-//
-val nl = phil_left (n) // = n
-val nr = phil_right (n) // = (n+1) % 5
-//
-val ch_lfork = fork_changet (nl)
-val ch_rfork = fork_changet (nr)
-//
-val lf = channel_takeout (ch_lfork)
-val () = println! ("phil_loop(", n, ") picks left fork")
-//
-val () = randsleep (2) // sleep up to 2 seconds
-//
-val rf = channel_takeout (ch_rfork)
-val () = println! ("phil_loop(", n, ") picks right fork")
-//
-val () = phil_dine (n, lf, rf)
-//
-val ch_forktray = forktray_changet ()
-val () = channel_insert (ch_forktray, lf) // left fork to dirty tray
-val () = channel_insert (ch_forktray, rf) // right fork to dirty tray
-//
-in
-  phil_loop (n)
-end // end of [phil_loop]
-')
- -It should be straighforward to follow the code for [phil_loop]. - -

-Fork Cleaner Loop -

- -A cleaner is implemented as a loop: - -
-#pats2xhtml_dats('\
-implement
-cleaner_loop () = let
-//
-val ch = forktray_changet ()
-val f0 = channel_takeout (ch) // [f0] is dirty
-//
-val () = cleaner_wash (f0) // washes dirty [f0]
-val () = cleaner_return (f0) // puts back cleaned [f0]
-//
-in
-  cleaner_loop ()
-end // end of [cleaner_loop]
-')
- -The function [cleaner_return] first finds out the number of a given fork -and then uses the number to locate the channel for storing the fork. Its -actual implementation is given as follows: - -
-#pats2xhtml_dats('\
-implement
-cleaner_return (f) =
-{
-  val n = fork_get_num (f)
-  val ch = fork_changet (n)
-  val () = channel_insert (ch, f)
-}
-')
- -It should now be straighforward to follow the code for [cleaner_loop]. - -

-Testing -

- -The entire code of this implementation is stored in the following files: - -
-DiningPhil2.sats
-DiningPhil2.dats
-DiningPhil2_fork.dats
-DiningPhil2_thread.dats
-
- -There is also a Makefile available for compiling the ATS source code into -an excutable for testing. One should be able to encounter a deadlock after -running the simulation for a while. - -
- -This article is written by Hongwei Xi. - - - - -%{ -implement main () = fprint_filsub (stdout_ref, "main_atxt.txt") -%} diff --git a/samples/C++/qsciprinter.cp b/samples/C++/qsciprinter.cp new file mode 100644 index 00000000..f30d6454 --- /dev/null +++ b/samples/C++/qsciprinter.cp @@ -0,0 +1,116 @@ +// This module defines interface to the QsciPrinter class. +// +// Copyright (c) 2011 Riverbank Computing Limited +// +// This file is part of QScintilla. +// +// This file may be used under the terms of the GNU General Public +// License versions 2.0 or 3.0 as published by the Free Software +// Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +// included in the packaging of this file. Alternatively you may (at +// your option) use any later version of the GNU General Public +// License if such license has been publicly approved by Riverbank +// Computing Limited (or its successors, if any) and the KDE Free Qt +// Foundation. In addition, as a special exception, Riverbank gives you +// certain additional rights. These rights are described in the Riverbank +// GPL Exception version 1.1, which can be found in the file +// GPL_EXCEPTION.txt in this package. +// +// If you are unsure which license is appropriate for your use, please +// contact the sales department at sales@riverbankcomputing.com. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + +#ifndef QSCIPRINTER_H +#define QSCIPRINTER_H + +#ifdef __APPLE__ +extern "C++" { +#endif + +#include + +#include +#include + + +QT_BEGIN_NAMESPACE +class QRect; +class QPainter; +QT_END_NAMESPACE + +class QsciScintillaBase; + + +//! \brief The QsciPrinter class is a sub-class of the Qt QPrinter class that +//! is able to print the text of a Scintilla document. +//! +//! The class can be further sub-classed to alter to layout of the text, adding +//! headers and footers for example. +class QSCINTILLA_EXPORT QsciPrinter : public QPrinter +{ +public: + //! Constructs a printer paint device with mode \a mode. + QsciPrinter(PrinterMode mode = ScreenResolution); + + //! Destroys the QsciPrinter instance. + virtual ~QsciPrinter(); + + //! Format a page, by adding headers and footers for example, before the + //! document text is drawn on it. \a painter is the painter to be used to + //! add customised text and graphics. \a drawing is true if the page is + //! actually being drawn rather than being sized. \a painter drawing + //! methods must only be called when \a drawing is true. \a area is the + //! area of the page that will be used to draw the text. This should be + //! modified if it is necessary to reserve space for any customised text or + //! graphics. By default the area is relative to the printable area of the + //! page. Use QPrinter::setFullPage() because calling printRange() if you + //! want to try and print over the whole page. \a pagenr is the number of + //! the page. The first page is numbered 1. + virtual void formatPage(QPainter &painter, bool drawing, QRect &area, + int pagenr); + + //! Return the number of points to add to each font when printing. + //! + //! \sa setMagnification() + int magnification() const {return mag;} + + //! Sets the number of points to add to each font when printing to \a + //! magnification. + //! + //! \sa magnification() + virtual void setMagnification(int magnification); + + //! Print a range of lines from the Scintilla instance \a qsb. \a from is + //! the first line to print and a negative value signifies the first line + //! of text. \a to is the last line to print and a negative value + //! signifies the last line of text. true is returned if there was no + //! error. + virtual int printRange(QsciScintillaBase *qsb, int from = -1, int to = -1); + + //! Return the line wrap mode used when printing. The default is + //! QsciScintilla::WrapWord. + //! + //! \sa setWrapMode() + QsciScintilla::WrapMode wrapMode() const {return wrap;} + + //! Sets the line wrap mode used when printing to \a wmode. + //! + //! \sa wrapMode() + virtual void setWrapMode(QsciScintilla::WrapMode wmode); + +private: + int mag; + QsciScintilla::WrapMode wrap; + + QsciPrinter(const QsciPrinter &); + QsciPrinter &operator=(const QsciPrinter &); +}; + +#ifdef __APPLE__ +} +#endif + +#endif diff --git a/samples/CLIPS/demo.clp b/samples/CLIPS/demo.clp new file mode 100644 index 00000000..45cb4828 --- /dev/null +++ b/samples/CLIPS/demo.clp @@ -0,0 +1,343 @@ +;;;*************************** +;;;* DEFFACTS KNOWLEDGE BASE * +;;;*************************** + +(deffacts MAIN::knowledge-base + (welcome (message WelcomeMessage)) + (goal (variable type.animal)) + (legalanswers (values yes no)) + (displayanswers (values "Yes" "No")) + (rule (if backbone is yes) + (then superphylum is backbone)) + (rule (if backbone is no) + (then superphylum is jellyback)) + (question (variable backbone) + (query backbone.query)) + (rule (if superphylum is backbone and + warm.blooded is yes) + (then phylum is warm)) + (rule (if superphylum is backbone and + warm.blooded is no) + (then phylum is cold)) + (question (variable warm.blooded) + (query warm.blooded.query)) + (rule (if superphylum is jellyback and + live.prime.in.soil is yes) + (then phylum is soil)) + (rule (if superphylum is jellyback and + live.prime.in.soil is no) + (then phylum is elsewhere)) + (question (variable live.prime.in.soil) + (query live.prime.in.soil.query)) + (rule (if phylum is warm and + has.breasts is yes) + (then class is breasts)) + (rule (if phylum is warm and + has.breasts is no) + (then type.animal is bird)) + (question (variable has.breasts) + (query has.breasts.query)) + (rule (if phylum is cold and + always.in.water is yes) + (then class is water)) + (rule (if phylum is cold and + always.in.water is no) + (then class is dry)) + (question (variable always.in.water) + (query always.in.water.query)) + (rule (if phylum is soil and + flat.bodied is yes) + (then type.animal is flatworm)) + (rule (if phylum is soil and + flat.bodied is no) + (then type.animal is worm.leech)) + (question (variable flat.bodied) + (query flat.bodied.query)) + (rule (if phylum is elsewhere and + body.in.segments is yes) + (then class is segments)) + (rule (if phylum is elsewhere and + body.in.segments is no) + (then class is unified)) + (question (variable body.in.segments) + (query body.in.segments.query)) + (rule (if class is breasts and + can.eat.meat is yes) + (then order is meat)) + (rule (if class is breasts and + can.eat.meat is no) + (then order is vegy)) + (question (variable can.eat.meat) + (query can.eat.meat.query)) + (rule (if class is water and + boney is yes) + (then type.animal is fish)) + (rule (if class is water and + boney is no) + (then type.animal is shark.ray)) + (question (variable boney) + (query boney.query)) + (rule (if class is dry and + scaly is yes) + (then order is scales)) + (rule (if class is dry and + scaly is no) + (then order is soft)) + (question (variable scaly) + (query scaly.query)) + (rule (if class is segments and + shell is yes) + (then order is shell)) + (rule (if class is segments and + shell is no) + (then type.animal is centipede.millipede.insect)) + (question (variable shell) + (query shell.query)) + (rule (if class is unified and + digest.cells is yes) + (then order is cells)) + (rule (if class is unified and + digest.cells is no) + (then order is stomach)) + (question (variable digest.cells) + (query digest.cells.query)) + (rule (if order is meat and + fly is yes) + (then type.animal is bat)) + (rule (if order is meat and + fly is no) + (then family is nowings)) + (question (variable fly) + (query fly.query)) + (rule (if order is vegy and + hooves is yes) + (then family is hooves)) + (rule (if order is vegy and + hooves is no) + (then family is feet)) + (question (variable hooves) + (query hooves.query)) + (rule (if order is scales and + rounded.shell is yes) + (then type.animal is turtle)) + (rule (if order is scales and + rounded.shell is no) + (then family is noshell)) + (question (variable rounded.shell) + (query rounded.shell.query)) + (rule (if order is soft and + jump is yes) + (then type.animal is frog)) + (rule (if order is soft and + jump is no) + (then type.animal is salamander)) + (question (variable jump) + (query jump.query)) + (rule (if order is shell and + tail is yes) + (then type.animal is lobster)) + (rule (if order is shell and + tail is no) + (then type.animal is crab)) + (question (variable tail) + (query tail.query)) + (rule (if order is cells and + stationary is yes) + (then family is stationary)) + (rule (if order is cells and + stationary is no) + (then type.animal is jellyfish)) + (question (variable stationary) + (query stationary.query)) + (rule (if order is stomach and + multicelled is yes) + (then family is multicelled)) + (rule (if order is stomach and + multicelled is no) + (then type.animal is protozoa)) + (question (variable multicelled) + (query multicelled.query)) + (rule (if family is nowings and + opposing.thumb is yes) + (then genus is thumb)) + (rule (if family is nowings and + opposing.thumb is no) + (then genus is nothumb)) + (question (variable opposing.thumb) + (query opposing.thumb.query)) + (rule (if family is hooves and + two.toes is yes) + (then genus is twotoes)) + (rule (if family is hooves and + two.toes is no) + (then genus is onetoe)) + (question (variable two.toes) + (query two.toes.query)) + (rule (if family is feet and + live.in.water is yes) + (then genus is water)) + (rule (if family is feet and + live.in.water is no) + (then genus is dry)) + (question (variable live.in.water) + (query live.in.water.query)) + (rule (if family is noshell and + limbs is yes) + (then type.animal is crocodile.alligator)) + (rule (if family is noshell and + limbs is no) + (then type.animal is snake)) + (question (variable limbs) + (query limbs.query)) + (rule (if family is stationary and + spikes is yes) + (then type.animal is sea.anemone)) + (rule (if family is stationary and + spikes is no) + (then type.animal is coral.sponge)) + (question (variable spikes) + (query spikes.query)) + (rule (if family is multicelled and + spiral.shell is yes) + (then type.animal is snail)) + (rule (if family is multicelled and + spiral.shell is no) + (then genus is noshell)) + (question (variable spiral.shell) + (query spiral.shell.query)) + (rule (if genus is thumb and + prehensile.tail is yes) + (then type.animal is monkey)) + (rule (if genus is thumb and + prehensile.tail is no) + (then species is notail)) + (question (variable prehensile.tail) + (query prehensile.tail.query)) + (rule (if genus is nothumb and + over.400 is yes) + (then species is 400)) + (rule (if genus is nothumb and + over.400 is no) + (then species is under400)) + (question (variable over.400) + (query over.400.query)) + (rule (if genus is twotoes and + horns is yes) + (then species is horns)) + (rule (if genus is twotoes and + horns is no) + (then species is nohorns)) + (question (variable horns) + (query horns.query)) + (rule (if genus is onetoe and + plating is yes) + (then type.animal is rhinoceros)) + (rule (if genus is onetoe and + plating is no) + (then type.animal is horse.zebra)) + (question (variable plating) + (query plating.query)) + (rule (if genus is water and + hunted is yes) + (then type.animal is whale)) + (rule (if genus is water and + hunted is no) + (then type.animal is dolphin.porpoise)) + (question (variable hunted) + (query hunted.query)) + (rule (if genus is dry and + front.teeth is yes) + (then species is teeth)) + (rule (if genus is dry and + front.teeth is no) + (then species is noteeth)) + (question (variable front.teeth) + (query front.teeth.query)) + (rule (if genus is noshell and + bivalve is yes) + (then type.animal is clam.oyster)) + (rule (if genus is noshell and + bivalve is no) + (then type.animal is squid.octopus)) + (question (variable bivalve) + (query bivalve.query)) + (rule (if species is notail and + nearly.hairless is yes) + (then type.animal is man)) + (rule (if species is notail and + nearly.hairless is no) + (then subspecies is hair)) + (question (variable nearly.hairless) + (query nearly.hairless.query)) + (rule (if species is 400 and + land.based is yes) + (then type.animal is bear.tiger.lion)) + (rule (if species is 400 and + land.based is no) + (then type.animal is walrus)) + (question (variable land.based) + (query land.based.query)) + (rule (if species is under400 and + thintail is yes) + (then type.animal is cat)) + (rule (if species is under400 and + thintail is no) + (then type.animal is coyote.wolf.fox.dog)) + (question (variable thintail) + (query thintail.query)) + (rule (if species is nohorns and + lives.in.desert is yes) + (then type.animal is camel)) + (rule (if species is nohorns and + lives.in.desert is no and + semi.aquatic is no) + (then type.animal is giraffe)) + (rule (if species is nohorns and + lives.in.desert is no and + semi.aquatic is yes) + (then type.animal is hippopotamus)) + (question (variable lives.in.desert) + (query lives.in.desert.query)) + (question (variable semi.aquatic) + (query semi.aquatic.query)) + (rule (if species is teeth and + large.ears is yes) + (then type.animal is rabbit)) + (rule (if species is teeth and + large.ears is no) + (then type.animal is rat.mouse.squirrel.beaver.porcupine)) + (question (variable large.ears) + (query large.ears.query)) + (rule (if species is noteeth and + pouch is yes) + (then type.animal is kangaroo.koala.bear)) + (rule (if species is noteeth and + pouch is no) + (then type.animal is mole.shrew.elephant)) + (question (variable pouch) + (query pouch.query)) + (rule (if subspecies is hair and + long.powerful.arms is yes) + (then type.animal is orangutan.gorilla.chimpanzee)) + (rule (if subspecies is hair and + long.powerful.arms is no) + (then type.animal is baboon)) + (question (variable long.powerful.arms) + (query long.powerful.arms.query)) + (rule (if species is horns and + fleece is yes) + (then type.animal is sheep.goat)) + (rule (if species is horns and + fleece is no) + (then subsubspecies is nofleece)) + (question (variable fleece) + (query fleece.query)) + (rule (if subsubspecies is nofleece and + domesticated is yes) + (then type.animal is cow)) + (rule (if subsubspecies is nofleece and + domesticated is no) + (then type.animal is deer.moose.antelope)) + (question (variable domesticated) + (query domesticated.query)) + (answer (prefix "I think your animal is a ") (variable type.animal) (postfix "."))) diff --git a/samples/CLIPS/sudoku.clp b/samples/CLIPS/sudoku.clp new file mode 100644 index 00000000..cbdbb92d --- /dev/null +++ b/samples/CLIPS/sudoku.clp @@ -0,0 +1,281 @@ +;;; http://www.angusj.com/sudoku/hints +;;; http://www.scanraid.com/BasicStrategies.htm +;;; http://www.sudokuoftheday.com/pages/techniques-overview +;;; http://www.sudokuonline.us/sudoku_solving_techniques +;;; http://www.sadmansoftware.com/sudoku/techniques.htm +;;; http://www.krazydad.com/blog/2005/09/29/an-index-of-sudoku-strategies/ + +;;; ####################### +;;; DEFTEMPLATES & DEFFACTS +;;; ####################### + +(deftemplate possible + (slot row) + (slot column) + (slot value) + (slot group) + (slot id)) + +(deftemplate impossible + (slot id) + (slot value) + (slot priority) + (slot reason)) + +(deftemplate technique-employed + (slot reason) + (slot priority)) + +(deftemplate technique + (slot name) + (slot priority)) + +(deffacts startup + (phase grid-values)) + +(deftemplate size-value + (slot size) + (slot value)) + +(deffacts values + (size-value (size 1) (value 1)) + (size-value (size 2) (value 2)) + (size-value (size 2) (value 3)) + (size-value (size 2) (value 4)) + (size-value (size 3) (value 5)) + (size-value (size 3) (value 6)) + (size-value (size 3) (value 7)) + (size-value (size 3) (value 8)) + (size-value (size 3) (value 9)) + (size-value (size 4) (value 10)) + (size-value (size 4) (value 11)) + (size-value (size 4) (value 12)) + (size-value (size 4) (value 13)) + (size-value (size 4) (value 14)) + (size-value (size 4) (value 15)) + (size-value (size 4) (value 16)) + (size-value (size 5) (value 17)) + (size-value (size 5) (value 18)) + (size-value (size 5) (value 19)) + (size-value (size 5) (value 20)) + (size-value (size 5) (value 21)) + (size-value (size 5) (value 22)) + (size-value (size 5) (value 23)) + (size-value (size 5) (value 24)) + (size-value (size 5) (value 25))) + +;;; ########### +;;; SETUP RULES +;;; ########### + +;;; *********** +;;; stress-test +;;; *********** + +(defrule stress-test + + (declare (salience 10)) + + (phase match) + + (stress-test) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (technique (priority ?next&:(> ?next ?last))) + + (not (technique (priority ?p&:(> ?p ?last)&:(< ?p ?next)))) + + => + + (assert (priority ?next))) + +;;; ***************** +;;; enable-techniques +;;; ***************** + +(defrule enable-techniques + + (declare (salience 10)) + + (phase match) + + (size ?) + + (not (possible (value any))) + + => + + (assert (priority 1))) + +;;; ********** +;;; expand-any +;;; ********** + +(defrule expand-any + + (declare (salience 10)) + + (phase expand-any) + + ?f <- (possible (row ?r) (column ?c) (value any) (group ?g) (id ?id)) + + (not (possible (value any) (id ?id2&:(< ?id2 ?id)))) + + (size ?s) + + (size-value (size ?as&:(<= ?as ?s)) (value ?v)) + + (not (possible (row ?r) (column ?c) (value ?v))) + + (not (and (size-value (value ?v2&:(< ?v2 ?v))) + + (not (possible (row ?r) (column ?c) (value ?v2))))) + + => + + (assert (possible (row ?r) (column ?c) (value ?v) (group ?g) (id ?id)))) + +;;; ***************** +;;; position-expanded +;;; ***************** + +(defrule position-expanded + + (declare (salience 10)) + + (phase expand-any) + + ?f <- (possible (row ?r) (column ?c) (value any) (group ?g) (id ?id)) + + (size ?s) + + (not (and (size-value (size ?as&:(<= ?as ?s)) (value ?v)) + + (not (possible (row ?r) (column ?c) (value ?v))))) + + => + + (retract ?f)) + +;;; ########### +;;; PHASE RULES +;;; ########### + +;;; *************** +;;; expand-any-done +;;; *************** + +(defrule expand-any-done + + (declare (salience 10)) + + ?f <- (phase expand-any) + + (not (possible (value any))) + + => + + (retract ?f) + + (assert (phase initial-output)) + (assert (print-position 1 1))) + +;;; *********** +;;; begin-match +;;; *********** + +(defrule begin-match + + (declare (salience -20)) + + ?f <- (phase initial-output) + + => + + (retract ?f) + + (assert (phase match))) + +;;; ***************** +;;; begin-elimination +;;; ***************** + +(defrule begin-elimination + + (declare (salience -20)) + + ?f <- (phase match) + + (not (not (impossible))) + + => + + (retract ?f) + + (assert (phase elimination))) + +;;; ************* +;;; next-priority +;;; ************* + +(defrule next-priority + + (declare (salience -20)) + + (phase match) + + (not (impossible)) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (technique (priority ?next&:(> ?next ?last))) + + (not (technique (priority ?p&:(> ?p ?last)&:(< ?p ?next)))) + + => + + (assert (priority ?next))) + +;;; ************ +;;; begin-output +;;; ************ + +(defrule begin-output + + (declare (salience -20)) + + ?f <- (phase match) + + (not (impossible)) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (not (technique (priority ?next&:(> ?next ?last)))) + + => + + (retract ?f) + + (assert (phase final-output)) + (assert (print-position 1 1))) + + + + + + + + + + + + + + diff --git a/samples/Common Lisp/sample.lsp b/samples/Common Lisp/sample.lsp new file mode 100644 index 00000000..9bef6781 --- /dev/null +++ b/samples/Common Lisp/sample.lsp @@ -0,0 +1,21 @@ +;;;; -*- lisp -*- + +(in-package :foo) + +;;; Header comment. +(defvar *foo*) + +(eval-when (:execute :compile-toplevel :load-toplevel) + (defun add (x &optional y &key z) + (declare (ignore z)) + ;; Inline comment. + (+ x (or y 1)))) + +#| +Multi-line comment. +|# + +(defmacro foo (x &body b) + (if x + `(1+ ,x) ;After-line comment. + 42)) diff --git a/samples/Emacs Lisp/.emacs.desktop b/samples/Emacs Lisp/.emacs.desktop new file mode 100644 index 00000000..499e44bb --- /dev/null +++ b/samples/Emacs Lisp/.emacs.desktop @@ -0,0 +1,29 @@ +;; -*- mode: emacs-lisp; coding: emacs-mule; -*- +;; -------------------------------------------------------------------------- +;; Desktop File for Emacs +;; -------------------------------------------------------------------------- +;; Created Sat Jan 3 12:46:35 2015 +;; Desktop file format version 206 +;; Emacs version 24.3.1 + +;; Global section: +(setq desktop-missing-file-warning nil) +(setq tags-file-name nil) +(setq tags-table-list nil) +(setq search-ring nil) +(setq regexp-search-ring nil) +(setq register-alist nil) +(setq file-name-history nil) + +;; Buffer section -- buffers listed in same order as in buffer list: +(desktop-create-buffer 206 + "/home/foo/bar" + "bar" + 'fundamental-mode + nil + 11572 + '(11554 nil) + nil + nil + '((buffer-file-coding-system . undecided-unix))) + diff --git a/samples/Forth/tools.4TH b/samples/Forth/tools.4TH new file mode 100644 index 00000000..b08a29fe --- /dev/null +++ b/samples/Forth/tools.4TH @@ -0,0 +1,133 @@ +\ -*- forth -*- Copyright 2004, 2013 Lars Brinkhoff + +( Tools words. ) + +: .s ( -- ) + [char] < emit depth (.) ." > " + 'SP @ >r r@ depth 1- cells + + begin + dup r@ <> + while + dup @ . + /cell - + repeat r> 2drop ; + +: ? @ . ; + +: c? c@ . ; + +: dump bounds do i ? /cell +loop cr ; + +: cdump bounds do i c? loop cr ; + +: again postpone branch , ; immediate + +: see-find ( caddr -- end xt ) + >r here lastxt @ + begin + dup 0= abort" Undefined word" + dup r@ word= if r> drop exit then + nip dup >nextxt + again ; + +: cabs ( char -- |char| ) dup 127 > if 256 swap - then ; + +: xt. ( xt -- ) + ( >name ) count cabs type ; + +: xt? ( xt -- flag ) + >r lastxt @ begin + ?dup + while + dup r@ = if r> 2drop -1 exit then + >nextxt + repeat r> drop 0 ; + +: disassemble ( x -- ) + dup xt? if + ( >name ) count + dup 127 > if ." postpone " then + cabs type + else + . + then ; + +: .addr dup . ; + +: see-line ( addr -- ) + cr ." ( " .addr ." ) " @ disassemble ; + +: see-word ( end xt -- ) + >r ." : " r@ xt. + r@ >body do i see-line /cell +loop + ." ;" r> c@ 127 > if ." immediate" then ; + +: see bl word see-find see-word cr ; + +: #body bl word see-find >body - ; + +: type-word ( end xt -- flag ) + xt. space drop 0 ; + +: traverse-dictionary ( in.. xt -- out.. ) + \ xt execution: ( in.. end xt2 -- in.. 0 | in.. end xt2 -- out.. true ) + >r here lastxt @ begin + ?dup + while + r> 2dup >r >r execute + if r> r> 2drop exit then + r> dup >nextxt + repeat r> 2drop ; + +: words ( -- ) + ['] type-word traverse-dictionary cr ; + +\ ---------------------------------------------------------------------- + +( Tools extension words. ) + +\ ;code + +\ assembler + +\ in kernel: bye + +\ code + +\ cs-pick + +\ cs-roll + +\ editor + +: forget ' dup >nextxt lastxt ! 'here ! reveal ; + +\ Kernel: state + +\ [else] + +\ [if] + +\ [then] + +\ ---------------------------------------------------------------------- + +( Forth2012 tools extension words. ) + +\ TODO: n>r + +\ TODO: nr> + +\ TODO: synonym + +: [undefined] bl-word find nip 0= ; immediate + +: [defined] postpone [undefined] invert ; immediate + +\ ---------------------------------------------------------------------- + +: @+ ( addr -- addr+/cell x ) dup cell+ swap @ ; + +: !+ ( x addr -- addr+/cell ) tuck ! cell+ ; + +: -rot swap >r swap r> ; diff --git a/samples/GAP/bugfix.tst b/samples/GAP/bugfix.tst new file mode 100644 index 00000000..be4bd975 --- /dev/null +++ b/samples/GAP/bugfix.tst @@ -0,0 +1,161 @@ +gap> START_TEST("Test for various former bugs"); + + +gap> # The following used to trigger an error starting with: +gap> # "SolutionMat: matrix and vector incompatible called from" +gap> K:=AbelianPcpGroup([3,3,3]);; +gap> A:=Subgroup(K,[K.1]);; +gap> cr:=CRRecordBySubgroup(K,A);; +gap> ExtensionsCR(cr);; + + +# Comparing homomorphisms used to be broken +gap> K:=AbelianPcpGroup(1,[3]);; +gap> hom1:=GroupHomomorphismByImages(K,K,[K.1],[K.1]);; +gap> hom2:=GroupHomomorphismByImages(K,K,[K.1^2],[K.1^2]);; +gap> hom1=hom2; +true +gap> hom1=IdentityMapping(K); +true +gap> hom2=IdentityMapping(K); +true + + +gap> # The following incorrectly triggered an error at some point +gap> IsTorsionFree(ExamplesOfSomePcpGroups(5)); +true + + +gap> # Verify IsGeneratorsOfMagmaWithInverses warnings are silenced +gap> IsGeneratorsOfMagmaWithInverses(GeneratorsOfGroup(ExamplesOfSomePcpGroups(5))); +true + + +gap> # Check for a bug reported 2012-01-19 by Robert Morse +gap> g := PcGroupToPcpGroup(SmallGroup(48,1)); +Pcp-group with orders [ 2, 2, 2, 2, 3 ] +gap> # The next two commands used to trigger errors +gap> NonAbelianTensorSquare(Centre(g)); +Pcp-group with orders [ 8 ] +gap> NonAbelianExteriorSquare(Centre(g)); +Pcp-group with orders [ ] + + +gap> # Check for a bug reported 2012-01-19 by Robert Morse +gap> F := FreeGroup("x","y"); + +gap> x := F.1;; y := F.2;; +gap> G := F/[x^2/y^24, y^24, y^x/y^23]; + +gap> iso := IsomorphismPcGroup(G); +[ x, y ] -> [ f1, f2*f5 ] +gap> iso1 := IsomorphismPcpGroup(Image(iso)); +[ f1, f2, f3, f4, f5 ] -> [ g1, g2, g3, g4, g5 ] +gap> G := Image(iso*iso1); +Pcp-group with orders [ 2, 2, 2, 2, 3 ] +gap> # The next command used to trigger an error +gap> NonAbelianTensorSquare(Image(iso*iso1)); +Pcp-group with orders [ 2, 2, 3, 2, 2, 2, 2 ] + + +gap> # The problem with the previous example is/was that Igs(G) +gap> # is set to a non-standard value: +gap> Igs(G); +[ g1, g2*g5, g3*g4*g5^2, g4*g5, g5 ] +gap> # Unfortunately, it seems that a lot of code that +gap> # really should be using Ngs or Cgs is using Igs incorrectly. +gap> # For example, direct products could return *invalid* embeddings: +gap> D := DirectProduct(G, G); +Pcp-group with orders [ 2, 2, 2, 2, 3, 2, 2, 2, 2, 3 ] +gap> hom:=Embedding(D,1);; +gap> mapi:=MappingGeneratorsImages(hom);; +gap> GroupHomomorphismByImages(Source(hom),Range(hom),mapi[1],mapi[2]) <> fail; +true +gap> hom:=Projection(D,1);; +gap> mapi:=MappingGeneratorsImages(hom);; +gap> GroupHomomorphismByImages(Source(hom),Range(hom),mapi[1],mapi[2]) <> fail; +true + + +gap> # Check for bug computing Schur extension of infinite cyclic groups, +gap> # found by Max Horn 2012-05-25 +gap> G:=AbelianPcpGroup(1,[0]); +Pcp-group with orders [ 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(G); +Pcp-group with orders [ 0 ] + + +gap> # Check for bug computing Schur extensions of subgroups, found by MH 2012-05-25. +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> H:=Subgroup(G,[G.2^3*G.3^2, G.1^9]); +Pcp-group with orders [ 0, 0, 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(H); +Pcp-group with orders [ 0, 0, 0, 0, 0, 0 ] + + +gap> # Check for bug computing Schur extensions of subgroups, found by MH 2012-05-25. +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> H:=Subgroup(G,[G.1, G.2]); +Pcp-group with orders [ 0, 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(H); +Pcp-group with orders [ 0, 0, 0 ] + + +gap> # Check for bug computing normalizer of two subgroups, found by MH 2012-05-30. +gap> # The problem was caused by incorrect resp. overly restrictive use of Parent(). +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> A:=Subgroup(Subgroup(G,[G.2,G.3,G.4,G.5]), [G.3]); +Pcp-group with orders [ 0 ] +gap> B:=Subgroup(Subgroup(G,[G.1,G.4,G.5]), [G.4]); +Pcp-group with orders [ 0 ] +gap> Normalizer(A,B); +Pcp-group with orders [ 0 ] +gap> # The following used to trigger the error "arguments must have a common parent group" +gap> Normalizer(B,A); +Pcp-group with orders [ 0 ] + + +gap> # In polycyclic 2.9 and 2.10, the code for 2-cohomology computations was broken. +gap> G := UnitriangularPcpGroup(3,0); +Pcp-group with orders [ 0, 0, 0 ] +gap> mats := G!.mats; +[ [ [ 1, 1, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ], + [ [ 1, 0, 0 ], [ 0, 1, 1 ], [ 0, 0, 1 ] ], + [ [ 1, 0, 1 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] ] +gap> C := CRRecordByMats(G,mats);; +gap> cc := TwoCohomologyCR(C);; +gap> cc.factor.rels; +[ 2, 0, 0 ] +gap> c := cc.factor.prei[2]; +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1 ] +gap> cc.gcb; +[ [ 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1 ], + [ -1, 0, 1, 1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1 ] ] +gap> cc.gcc; +[ [ 1, 0, 0, 0, 0, -2, -1, 0, 1, 1, -1, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 1, 0, 0, -2, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 1, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1 ], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1 ] ] + + +gap> # LowerCentralSeriesOfGroup for non-nilpotent pcp-groups used to trigger +gap> # an infinite recursion +gap> G := PcGroupToPcpGroup(SmallGroup(6,1)); +Pcp-group with orders [ 2, 3 ] +gap> LowerCentralSeriesOfGroup(G); +[ Pcp-group with orders [ 2, 3 ], Pcp-group with orders [ 3 ] ] + + +gap> STOP_TEST( "bugfix.tst", 10000000); diff --git a/samples/GAP/factor.tst b/samples/GAP/factor.tst new file mode 100644 index 00000000..115fe921 --- /dev/null +++ b/samples/GAP/factor.tst @@ -0,0 +1,21 @@ +gap> START_TEST("Test of factor groups and natural homomorphisms"); + +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] + +gap> H:=Subgroup(G,[G.2,G.3,G.4,G.5]); +gap> K:=G/H; +gap> NaturalHomomorphism(K); + +gap> A:=Subgroup(H, [G.3]); +Pcp-group with orders [ 0 ] +gap> B:=Subgroup(Subgroup(G,[G.1,G.4,G.5]), [G.4]); +Pcp-group with orders [ 0 ] +gap> Normalizer(A,B); +Pcp-group with orders [ 0 ] +gap> # The following used to trigger the error "arguments must have a common parent group" +gap> Normalizer(B,A); +Pcp-group with orders [ 0 ] + + +gap> STOP_TEST( "factor.tst", 10000000); diff --git a/samples/HTML/index.html.hl b/samples/HTML/index.html.hl new file mode 100644 index 00000000..65491957 --- /dev/null +++ b/samples/HTML/index.html.hl @@ -0,0 +1,328 @@ + + + + + + + + +
+

Example 1

+ + + + + +
+ + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 2

+ + + + + +
+ + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 3

+ + + + + +
+ + + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 4

+ + + + + +
+ + +
+
+
+ + +
+

Example 5

+ + + + + +
+ + +
+
+
+ + +
+

Example 6

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 7

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 8

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 9

+ + + + + +
+ + +
+
+ + +
+

Example 10

+ + + + + +
+ + + +
+
+ + diff --git a/samples/J/stwij.ijs b/samples/J/stwij.ijs new file mode 100644 index 00000000..453af90b --- /dev/null +++ b/samples/J/stwij.ijs @@ -0,0 +1,73 @@ +NB. From "Continuing to write in J". +NB. See http://www.jsoftware.com/help/jforc/continuing_to_write_in_j.htm + +empno=: 316 317 319 320 +payrate=: 60 42 44 54 +billrate=: 120 90 90 108 +clientlist=: 10011 10012 10025 +emp_client=: 10012 10025 10012 10025 +hoursworked=: 4 31 $ 8 0 3 10 9 8 8 9 4 0 8 7 10 10 12 9 0 6 8 9 9 9 0 0 10 11 9 7 10 2 0 8 0 0 9 9 8 9 10 0 0 8 8 10 7 10 0 0 7 8 9 8 9 0 4 9 8 9 8 9 0 0 5 0 0 8 9 9 9 9 0 0 8 7 0 0 9 0 2 10 10 9 11 8 0 0 8 9 10 8 9 0 0 9 0 0 9 10 8 6 6 8 0 9 8 10 6 9 7 0 6 8 8 8 9 0 5 8 9 8 8 12 0 0 + +NB. Finds the number of hours each employee worked in the given month. +emphours=: 3 : '+/"1 hoursworked' + +NB. Determines the wages earned by each employee in the given month. +empearnings=: 3 : 'payrate * +/"1 hoursworked' + +NB. Determines the profit brought in by each employee. +empprofit=: 3 : 0 +(billrate - payrate) * +/"1 hoursworked +) + +NB. Returns the amount to bill a given client. +billclient=: 3 : 0 +mask=. emp_client = y ++/ (mask # billrate) * +/"1 mask # hoursworked +) + +NB. Finds for each day of the month the employee who billed the most hours. +dailydrudge=: 3 : 0 +((|: hoursworked) i."1 0 >./ hoursworked) { empno +) + +NB. Returns the employees, in descending order of the profit brought in by each. +producers=: 3 : 'empno \: empprofit 0' + +NB. Returns the clients, in descending order of the profit generated by each. +custbyprofit=: 3 : 0 +clientlist \: +/ (clientlist ="1 0 emp_client) * empprofit 0 +) + +NB. Calculates withholding tax on each employee's earnings. +renderuntocaesar=: 3 : 0 +bktmin=. 0 6000 10000 20000 NB. Four brackets, 0..6000..10000..20000.._ +bktrate=. 0.05 0.10 0.20 0.30 +bktearns=. 0 >. ((1 |.!._ bktmin) <."1 0 empearnings'') -"1 bktmin ++/"1 bktrate *"1 bktearns +) + +NB. Main + +echo 'Problem 1' +echo emphours'' + +echo 'Problem 2' +echo empearnings'' + +echo 'Problem 3' +echo empprofit'' + +echo 'Problem 4' +echo billclient 10025 + +echo 'Problem 5' +echo dailydrudge'' + +echo 'Problem 6' +echo producers'' + +echo 'Problem 7' +echo custbyprofit'' + +echo 'Problem 8' +echo 0j2 ": renderuntocaesar'' diff --git a/samples/Mathematica/HeyexImport.m b/samples/Mathematica/HeyexImport.m new file mode 100644 index 00000000..457a7e92 --- /dev/null +++ b/samples/Mathematica/HeyexImport.m @@ -0,0 +1,344 @@ +(* Mathematica Package *) +(* Created with IntelliJ IDEA and the Mathematica Language plugin *) + +(* :Title: Importer for the RAW data-format of the Heidelberg Eye Explorer (known as HEYEX) *) + +(* :Context: HeyexImport` *) + +(* :Author: Patrick Scheibe pscheibe@trm.uni-leipzig.de *) + +(* :Package Version: 1.0 *) + +(* :Mathematica Version: 8.0 *) + +(* :Copyright: Patrick Scheibe, 2013-2015 *) + +(* :Discussion: This package registers a new importer which can load the RAW data-format exported by a + Heidelberg Spectralis OCT. The import-functionality can access different information contained + in a file: + 1. The file header which contains meta data like when the patient was scanned etc + 2. The scanned volume data + 3. Images which represent slices of the scanned volume + 4. The Scanning laser ophthalmoscopy (SLO) image which is taken with every scanned patient + 5. The segmentation data for different retina layers provided by the software + +*) + +(* :Keywords: Import, Heyex, OCT, Spectralis, Heidelberg Engineering *) + +BeginPackage[ "HeyexImport`" ] + +HeyexEyePosition::usage = "HeyexEyePosition[file] tries to extract which eye was scanned, left or right."; + +HeyexImport::wrongHdr = "Error importing OCT data. Broken/Wrong file?"; + + +Begin[ "`Private`" ]; + +(* + Registration of all import possibilities for the Heidelberg OCT. +*) + +ImportExport`RegisterImport[ + "Heyex" , + { + "FileHeader" :> importHeader, + { "Data" , n_Integer} :> (importData[n][##]&), + "Data" :> importData, + { "Images" , n_Integer} :> (importImages[n][##]&), + "Images" :> importImages, + "SLOImage" :> importSLOImage, + "SegmentationData" :> importSegmentation, + { "SegmentationData" , n_Integer} :> (importSegmentation[n][##]&), + "DataSize" :> importDataSize, + importData + }, + + { + "Image3D" :> (Image3D["Data" /. #1]&) + }, + + "AvailableElements" -> {"FileHeader", "Data", "DataSize", "Images", "SLOImage", "SegmentationData", "Image3D"} +]; + + +If[Quiet[Check[TrueQ[Compile[{}, 0, CompilationTarget -> "C"][] == 0], False]], + $compileTarget = CompilationTarget -> "C", + $compileTarget = CompilationTarget -> "MVM" +]; + + +(* + Helper function which reads data from a stream. This is + only a unification so I can map the read function over a + list. +*) +read[{id_String, type_String}, str_] := +id -> BinaryRead[str, type]; +read[{type_String, n_Integer}, str_] := BinaryReadList[str, type, n]; +read[{id_String, {type_String, n_Integer}}, str_] := id -> BinaryReadList[str, type, n]; +(* + Note that when reading bytes explicitly I convert them to + a string and remove any zeroes at the end. +*) +read[{id_String, { "Byte" , n_Integer}}, str_] := +id -> StringJoin[ + FromCharacterCode /@ (Rest[ + NestList[BinaryRead[str, "Byte" ] &, Null, + n]] /. {chars___Integer, Longest[0 ...]} :> {chars})]; + +(* + The layout of a file exported with "Raw Export" + + ***************** + * File Header * + ***************** + * SLO Image * + ***************** + * B-Scan #0 * + ***************** + * ..... * + ***************** + * B-Scan #n-1 * + ***************** +*) + +With[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte"}, + + $fileHeaderInfo = Transpose[{ + { + "Version" , "SizeX" , "NumBScans" , "SizeZ" , "ScaleX" , "Distance" , + "ScaleZ" , "SizeXSlo" , "SizeYSlo" , "ScaleXSlo" , "ScaleYSlo" , + "FieldSizeSlo" , "ScanFocus" , "ScanPosition" , "ExamTime" , + "ScanPattern" , "BScanHdrSize" , "ID" , "ReferenceID" , "PID" , + "PatientID" , "Padding" , "DOB" , "VID" , "VisitID" , "VisitDate" , + "Spare" + }, + { + {b, 12}, i, i, i, d, d, d, i, i, d, d, i, d, {b, 4}, {i, 2}, i, i, + {b, 16}, {b, 16}, i, {b, 21}, {b, 3}, d, i, {b, 24}, d, {b, 1840} + } + }]; + + $bScanHeaderInfo = Transpose[{ + { + "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , + "NumSeg" , "OffSeg" , "Quality" , "Spare" + }, + {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}} + }]; +]; + + +isHeyexRawFormat[{"Version" -> version_String, "SizeX" -> _Integer, "NumBScans" -> _Integer, _Rule..}] /; StringMatchQ[version, "HSF-OCT" ~~__] := True ; +isHeyexRawFormat[___] := False; + +readFileHeader[str_InputStream] := With[{hdr = Quiet[read[#, str]] & /@ $fileHeaderInfo}, + hdr /; TrueQ[isHeyexRawFormat[hdr]] +]; +readFileHeader[___] := (Message[HeyexImport::wrongHdr]; Throw[$Failed]); + + +(* Reads the camera image of the retina. Note that you must have the + information from the fileheader and you must be at the right position + of the file stream for this.*) +readSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := + Image[Partition[ + BinaryReadList[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr], + "SizeXSlo" /. fileHdr], "Byte" ]; + +skipSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr]; + + +(* One single BScan consists itself again of a header and a data part *) +readBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := + Module[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte", + bScanHdr}, + bScanHdr = read[#, str] & /@ Transpose[{ + { "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , + "NumSeg" , "OffSeg" , "Quality" , "Spare" }, + {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}}} + ]; + AppendTo[bScanHdr, + read[{ "SegArray" , { "Real32" , + "NumSeg" * "SizeX" /. bScanHdr /. fileHdr}}, str] + ]; + (* + This is horrible slow, therefore I just skip the fillbytes + + AppendTo[bScanHdr, + read[{"Fillbytes", {"Byte", + "BScanHdrSize" - 256 - "NumSeg"*"SizeX"*4 /. bScanHdr /. + fileHdr}}, str] + ] + *) + Skip[str, "Byte" , "BScanHdrSize" - 256 - "NumSeg" * "SizeX" * 4 /. bScanHdr /. fileHdr]; + AppendTo[bScanHdr, "FillBytes" -> None] + ] + +skipBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "BScanHdrSize" /. fileHdr]; + +readBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := + Module[{}, + Developer`ToPackedArray[ + Partition[read[{ "Real32" , "SizeX" * "SizeZ" /. fileHdr}, str], + "SizeX" /. fileHdr]] + ]; + +skipBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "SizeX" * "SizeZ" * 4 /. fileHdr]; + +skipBScanBlocks[str_InputStream, fileHdr : {(_String -> _) ..}, n_Integer] := + Skip[str, "Byte" , n * ("BScanHdrSize" + "SizeX" * "SizeZ" * 4) /. fileHdr]; + + +importHeader[filename_String, ___] := Module[ + {str, header}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + Close[str]; + "FileHeader" -> header +]; + + +(* Imports the dimension of the scanned volume. *) +importDataSize[filename_String, r___] := Module[{header = importHeader[filename]}, + "DataSize" -> ({"NumBScans", "SizeZ", "SizeXSlo"} /. ("FileHeader" /. header)) +] + +importSLOImage[filename_String, ___] := Module[ + {str, header, slo}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + slo = readSLOImage[str, header]; + Close[str]; + "SLOImage" -> slo +] + +importData[filename_String, ___] := Module[ + {str, header, nx, n, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; + skipSLOImage[str, header]; + data = Table[ + skipBScanHeader[str, header]; + Partition[read[{ "Real32" , n}, str], nx], + {"NumBScans" /. header} + ]; + Close[str]; + "Data" -> Developer`ToPackedArray[data] +]; + +importData[num_Integer][filename_String, ___] := Module[ + {str, header, nx, n, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; + skipSLOImage[str, header]; + skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; + skipBScanHeader[str, header]; + data = Partition[read[{ "Real32" , n}, str], nx]; + Close[str]; + {"Data" -> {num -> Developer`ToPackedArray[data]}} +]; + +(* + As suggested in the Heidelberg OCT Manual the importer will adjust + the graylevels when importing images. Since this is very time-consuming + for the whole scanned volume, I use an optimized version of this function. +*) +With[{$compileTarget = $compileTarget}, $adjustGraylevelFunc := ($adjustGraylevelFunc = Compile[{{values, _Real, 2}}, + Map[Floor[255.0 * Min[Max[0.0, #], 1.0]^(0.25) + 0.5] &, values, {2}], + RuntimeAttributes -> {Listable}, + Parallelization -> True, + RuntimeOptions -> "Speed", + $compileTarget +])]; + +importImages[filename_String, ___] := Module[ + {data}, + data = "Data" /. importData[filename]; + "Images" -> (Image[#, "Byte" ]& /@ $adjustGraylevelFunc[data]) +] + +importImages[imageNumber_Integer][filename_String, ___] := Module[ + {data}, + data = {imageNumber /. ("Data" /. importData[imageNumber][filename])}; + {"Images" -> {imageNumber -> (Image[#, "Byte" ]& @@ $adjustGraylevelFunc[data])}} +]; + +importSegmentation[filename_String, ___] := Module[ + {str, header, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + skipSLOImage[str, header]; + data = Table[ + Module[{bScanHeader, t}, + {t, bScanHeader} = Timing@readBScanHeader[str, header]; + skipBScanData[str, header]; + bScanHeader + ], {"NumBScans" /. header} + ]; + Close[str]; + (* + The BScanHeaderData contain the segmentation vectors as a single list + of numbers. Before returning the result, I check how many segmentations + there are inside the BScan an I transform the segmentation value list + into separate vectors and call them "ILM", "RPE" and "NFL" like described + in the manual + *) + "SegmentationData" -> Function[{bhdr}, + Block[{numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, + If[numVecs > 0, + vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; + bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), + bhdr + ] + ]] /@ data +] + +importSegmentation[num_Integer][filename_String, ___] := Module[ + {str, header, bhdr}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + skipSLOImage[str, header]; + skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; + bhdr = readBScanHeader[str, header]; + Close[str]; + (* See doc above *) + {"SegmentationData" -> {num -> Block[ + {numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, + If[ numVecs > 0, + vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; + bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), + bhdr + ] + ] + }} +] + +(* Extracts which eye was scanned. This is stored in the header of the file *) +(* OD stands for oculus dexter which is latin for "right eye" and OS stands + for oculus sinister which is latin for "left eye" *) +HeyexEyePosition[file_String /; FileExistsQ[file]] := Module[{position}, + Check[ + position = "ScanPosition" /. Import[file, { "Heyex" , "FileHeader" }]; + Switch[ + position, + "OD" , + Right, + "OS" , + Left, + _, + $Failed + ], + $Failed + ] +]; + +End[] + +EndPackage[] \ No newline at end of file diff --git a/samples/Mercury/switch_detection_bug.m b/samples/Mercury/switch_detection_bug.m new file mode 100644 index 00000000..f96542c3 --- /dev/null +++ b/samples/Mercury/switch_detection_bug.m @@ -0,0 +1,46 @@ +% This is a regression test for a bug in switch detection +% where it was preferring incomplete switches to complete +% one-case switches, and hence inferring the wrong determinism. + +%------------------------------------------------------------------------------% + +:- module switch_detection_bug. + +:- interface. + +:- type note ---> note(rank, modifier, octave). + +:- type rank ---> c ; d ; e ; f ; g ; a ; b . + +:- type modifier ---> natural ; sharp ; flat . + +:- type octave == int. + +:- type qualifier ---> maj ; min . + +:- pred next_topnote(note, qualifier, note). +:- mode next_topnote(in, in, out) is multi. + +%------------------------------------------------------------------------------% + +:- implementation. + +next_topnote(note(c, _, Oct), _, note(d, natural, Oct)). +next_topnote(note(d, _, Oct), _, note(c, natural, Oct)). +next_topnote(note(d, _, Oct), maj, note(e, natural, Oct)). +next_topnote(note(d, _, Oct), min, note(e, flat, Oct)). +next_topnote(note(e, _, Oct), _, note(d, natural, Oct)). +next_topnote(note(e, _, Oct), _, note(f, natural, Oct)). +next_topnote(note(f, _, Oct), maj, note(e, natural, Oct)). +next_topnote(note(f, _, Oct), min, note(e, flat, Oct)). +next_topnote(note(g, _, Oct), _, note(f, natural, Oct)). +next_topnote(note(g, _, Oct), min, note(a, flat, Oct)). +next_topnote(note(g, _, Oct), maj, note(a, natural, Oct)). +next_topnote(note(a, _, Oct), _, note(g, natural, Oct)). +next_topnote(note(a, _, Oct), min, note(b, flat, Oct)). +next_topnote(note(a, _, Oct), maj, note(b, natural, Oct)). +next_topnote(note(b, _, Oct), maj, note(a, natural, Oct)). +next_topnote(note(b, _, Oct), min, note(a, flat, Oct)). + +%------------------------------------------------------------------------------% + diff --git a/samples/Modelica/Translational.mo b/samples/Modelica/Translational.mo new file mode 100644 index 00000000..62735f6a --- /dev/null +++ b/samples/Modelica/Translational.mo @@ -0,0 +1,5281 @@ +within Modelica.Mechanics; +package Translational + "Library to model 1-dimensional, translational mechanical systems" + extends Modelica.Icons.Package; + import SI = Modelica.SIunits; + + package Examples "Demonstration examples of the components of this package" + + extends Modelica.Icons.ExamplesPackage; + + model SignConvention "Examples for the used sign conventions." + extends Modelica.Icons.Example; + Translational.Components.Mass mass1(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{40,60},{60,80}}, rotation=0))); + Translational.Sources.Force force1 + annotation (Placement(transformation(extent={{ + -4,60},{16,80}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant1(k=1) + annotation (Placement(transformation(extent={{ + -44,60},{-24,80}}, rotation=0))); + Translational.Components.Mass mass2(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{40,0},{60,20}}, rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{ + -4,20},{16,40}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant2(k=1) + annotation (Placement(transformation(extent={{ + -44,20},{-24,40}}, rotation=0))); + Translational.Components.Mass mass3(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-40,-40},{-20,-20}}, rotation=0))); + Translational.Sources.Force force3(useSupport=true) + annotation (Placement(transformation(extent={{ + 20,-40},{0,-20}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant3(k=1) + annotation (Placement(transformation(extent={{ + 60,-40},{40,-20}}, rotation=0))); + Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{0,-60},{20,-40}}))); + equation + connect(constant1.y,force1. f) annotation (Line(points={{-23,70},{-6,70}}, + color={0,0,127})); + connect(constant2.y,force2. f) annotation (Line(points={{-23,30},{-6,30}}, + color={0,0,127})); + connect(constant3.y,force3. f) annotation (Line(points={{39,-30},{22,-30}}, + color={0,0,127})); + connect(force1.flange, mass1.flange_a) annotation (Line( + points={{16,70},{40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass2.flange_b) annotation (Line( + points={{16,30},{70,30},{70,10},{60,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass3.flange_b, force3.flange) annotation (Line( + points={{-20,-30},{0,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, force3.support) annotation (Line( + points={{10,-50},{10,-40}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+If all arrows point in the same direction a positive force +results in a positive acceleration a, velocity v and position s. +

+

+For a force of 1 N and a mass of 1 Kg this leads to +

+
+        a = 1 m/s2
+        v = 1 m/s after 1 s (SlidingMass1.v)
+        s = 0.5 m after 1 s (SlidingMass1.s)
+
+

+The acceleration is not available for plotting. +

+

+System 1) and 2) are equivalent. It doesn't matter whether the +force pushes at flange_a in system 1 or pulls at flange_b in system 2. +

+It is of course possible to ignore the arrows and connect the models +in an arbitrary way. But then it is hard see in what direction the +force acts. +

+In the third system the two arrows are opposed which means that the +force acts in the opposite direction (in the same direction as in +the two other examples). +

+"), Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Text( + extent={{-100,80},{-82,60}}, + textString="1)", + lineColor={0,0,255}), + Text( + extent={{-100,40},{-82,20}}, + textString="2)", + lineColor={0,0,255}), + Text( + extent={{-100,-20},{-82,-40}}, + textString="3)", + lineColor={0,0,255})}), + experiment(StopTime=1.0, Interval=0.001)); + end SignConvention; + + model InitialConditions "Setting of initial conditions" + + extends Modelica.Icons.Example; + + Translational.Components.Fixed fixed2( s0=1) + annotation (Placement(transformation( + extent={{-100,60},{-80,80}}, rotation=0))); + Translational.Components.Spring s2( s_rel0=2, c=1e3) + annotation (Placement( + transformation(extent={{-60,60},{-40,80}}, rotation=0))); + Translational.Components.Mass m3( L=3, s(start=4.5, fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-20,60},{0,80}}, rotation=0))); + Translational.Components.SpringDamper sd2( s_rel0=4, c=111, + d=1) annotation (Placement( + transformation(extent={{20,60},{40,80}}, rotation=0))); + Translational.Components.Mass m4( L=5, s(start=12.5, fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{60,60},{80,80}}, rotation=0))); + + Translational.Components.Fixed fixed1( s0=-1) + annotation (Placement(transformation( + extent={{-100,-20},{-80,0}}, rotation=0))); + Translational.Components.Spring s1( + s_rel0=1, + c=1e3, + s_rel(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-58,-20}, + {-38,0}}, rotation=0))); + Translational.Components.Mass m1( L=1, v(fixed=true), + m=1) annotation (Placement(transformation( + extent={{-20,-20},{0,0}}, rotation=0))); + Translational.Components.SpringDamper sd1( + s_rel0=1, + c=111, + s_rel(start=1, fixed=true), + v_rel(fixed=true), + d=1) annotation (Placement(transformation(extent={{20,-20},{ + 40,0}}, rotation=0))); + Translational.Components.Mass m2( L=2, m=1) + annotation (Placement(transformation( + extent={{60,-20},{80,0}}, rotation=0))); + equation + connect(s2.flange_a, fixed2.flange) annotation (Line( + points={{-60,70},{-90,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(s1.flange_a, fixed1.flange) annotation (Line( + points={{-58,-10},{-90,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m1.flange_a, s1.flange_b) annotation (Line( + points={{-20,-10},{-38,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sd1.flange_a, m1.flange_b) annotation (Line( + points={{20,-10},{0,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m2.flange_a, sd1.flange_b) annotation (Line( + points={{60,-10},{40,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m4.flange_a, sd2.flange_b) annotation (Line( + points={{60,70},{40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sd2.flange_a, m3.flange_b) annotation (Line( + points={{20,70},{0,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m3.flange_a, s2.flange_b) annotation (Line( + points={{-20,70},{-40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+There are several ways to set initial conditions. +In the first system the position of the mass m3 was defined +by using the modifier s(start=4.5), the position of m4 by s(start=12.5). +These positions were chosen such that the system is a rest. To calculate +these values start at the left (Fixed1) with a value of 1 m. The spring +has an unstretched length of 2 m and m3 an length of 3 m, which leads to +

+ +
+        1   m (fixed1)
+      + 2   m (spring s2)
+      + 3/2 m (half of the length of mass m3)
+      -------
+        4,5 m = s(start = 4.5) for m3
+      + 3/2 m (half of the length of mass m3)
+      + 4   m (springDamper 2)
+      + 5/2 m (half of length of mass m4)
+      -------
+       12,5 m = s(start = 12.5) for m4
+
+ +

+This selection of initial conditions has the effect that Dymola selects +those variables (m3.s and m4.s) as state variables. +In the second example the length of the springs are given as start values +but they cannot be used as state for pure springs (only for the spring/damper +combination). In this case the system is not at rest. +

+ +

+ +

+ +"), + experiment(StopTime=5.0, Interval=0.001)); + end InitialConditions; + + model WhyArrows "Use of arrows in Mechanics.Translational" + + extends Modelica.Icons.Example; + + Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{ + -20,20},{0,40}}, rotation=0))); + Translational.Components.Rod rod1( L=1) + annotation (Placement(transformation(extent={ + {-48,20},{-28,40}}, rotation=0))); + Translational.Components.Rod rod2( L=1) + annotation (Placement(transformation(extent={ + {20,20},{40,40}}, rotation=0))); + Translational.Components.Rod rod3( L=1) + annotation (Placement(transformation(extent={ + {-30,58},{-50,78}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor2 annotation (Placement( + transformation(extent={{60,20},{80,40}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor1 annotation (Placement( + transformation(extent={{-60,20},{-80,40}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor3 annotation (Placement( + transformation(extent={{-60,58},{-80,78}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=-1.9) + annotation (Placement(transformation( + extent={{-100,-60},{-80,-40}}, rotation=0))); + Translational.Components.Spring spring1( s_rel0=2, c=11) + annotation (Placement( + transformation(extent={{-80,-60},{-60,-40}}, rotation=0))); + Translational.Components.Mass mass1( + L=2, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-50,-60},{-30,-40}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=-1.9) + annotation (Placement(transformation( + extent={{0,-60},{20,-40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=2, c=11) + annotation (Placement( + transformation(extent={{30,-60},{50,-40}}, rotation=0))); + Translational.Components.Mass inertia2( L=2, + m=1, + s(fixed=true), + v(fixed=true)) annotation (Placement( + transformation(extent={{80,-60},{60,-40}}, rotation=0))); + equation + connect(spring1.flange_b, mass1.flange_b) annotation (Line(points={{-60,-50}, + {-60,-72},{-30,-72},{-30,-50}}, color={0,191,0})); + connect(spring2.flange_b, inertia2.flange_b) annotation (Line(points={{50,-50}, + {60,-50}}, color={0,191,0})); + connect(rod3.flange_b,positionSensor3. flange) annotation (Line( + points={{-50,68},{-60,68}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_a,positionSensor1. flange) annotation (Line( + points={{-48,30},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_b, fixed.flange) annotation (Line( + points={{-28,30},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod3.flange_a, fixed.flange) annotation (Line( + points={{-30,68},{-10,68},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, rod2.flange_a) annotation (Line( + points={{-10,30},{20,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod2.flange_b,positionSensor2. flange) annotation (Line( + points={{40,30},{60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed1.flange,spring1. flange_a) annotation (Line( + points={{-90,-50},{-80,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed2.flange,spring2. flange_a) annotation (Line( + points={{10,-50},{30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+When using the models of the translational sublibrary +it is recommended to make sure that all arrows point in +the same direction because then all component have the +same reference system. +In the example the distance from flange_a of Rod1 to flange_b +of Rod2 is 2 m. The distance from flange_a of Rod1 to flange_b +of Rod3 is also 2 m though it is difficult to see that. Without +the arrows it would be almost impossible to notice. +That all arrows point in the same direction is a sufficient +condition for an easy use of the library. There are cases +where horizontally flipped models can be used without +problems. +

+"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-84,10},{88,2}}, + lineColor={0,0,255}, + textString="positionSensor2.s = positionSensor3.s"), + Text( + extent={{-78,-4},{86,-12}}, + lineColor={0,0,255}, + textString="positionSensor3.s <>positionSensor1.s"), + Text( + extent={{-82,-80},{92,-88}}, + textString="Both systems are equivalent", + lineColor={0,0,255}), + Line( + points={{-90,-28},{90,-28}}, + thickness=0.5, + color={0,0,255})}), + experiment(StopTime=1.0, Interval=0.001)); + end WhyArrows; + + model Accelerate "Use of model accelerate." + + extends Modelica.Icons.Example; + Translational.Sources.Accelerate accelerate + annotation (Placement(transformation( + extent={{-40,20},{-20,40}}, rotation=0))); + Translational.Components.Mass mass(L=1, m=1) + annotation (Placement( + transformation(extent={{0,20},{20,40}}, rotation=0))); + Modelica.Blocks.Sources.Constant constantAcc(k=1) + annotation (Placement(transformation(extent={{-80,20}, + {-60,40}}, rotation=0))); + equation + connect(accelerate.flange, mass.flange_a) annotation (Line( + points={{-20,30},{0,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(constantAcc.y, accelerate.a_ref) annotation (Line( + points={{-59,30},{-42,30}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+Demonstrate usage of component Sources.Accelerate by moving a massing +with a predefined acceleration. +

+"), experiment(StopTime=1.0, Interval=0.001)); + end Accelerate; + + model Damper "Use of damper models." + + extends Modelica.Icons.Example; + + Translational.Components.Mass mass1( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,60},{-60, + 80}}, rotation=0))); + Translational.Components.Damper damper1( d=25) + annotation (Placement(transformation( + extent={{-20,60},{0,80}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=4.5) + annotation (Placement(transformation( + extent={{22,60},{42,80}}, rotation=0))); + Translational.Components.Mass mass2( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,0},{-60, + 20}}, rotation=0))); + Translational.Components.Damper damper2( d=25) + annotation (Placement(transformation( + extent={{-20,0},{0,20}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=4.5) + annotation (Placement(transformation( + extent={{20,0},{40,20}}, rotation=0))); + Translational.Components.Mass mass3( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,-60},{-60, + -40}}, rotation=0))); + Translational.Components.Fixed fixed3( s0=4.5) + annotation (Placement(transformation( + extent={{20,-60},{40,-40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=1, c=1) + annotation (Placement( + transformation(extent={{-20,-20},{0,0}}, rotation=0))); + Translational.Components.SpringDamper springDamper3( s_rel0=1, d=25, + c=1) annotation (Placement( + transformation(extent={{-20,-60},{0,-40}}, rotation=0))); + equation + connect(mass1.flange_b, damper1.flange_a) annotation (Line(points= + {{-60,70},{-20,70}}, color={0,191,0})); + connect(mass2.flange_b, damper2.flange_a) annotation (Line(points={{-60,10}, + {-20,10}}, color={0,191,0})); + connect(damper2.flange_b,spring2. flange_b) annotation (Line(points={{0, + 10},{0,-10}}, color={0,191,0})); + connect(damper2.flange_a,spring2. flange_a) annotation (Line(points={{-20, + 10},{-20,-10}}, color={0,191,0})); + connect(mass3.flange_b, springDamper3.flange_a) annotation (Line( + points={{-60,-50},{-20,-50}}, color={0,191,0})); + connect(damper1.flange_b, fixed1.flange) annotation (Line( + points={{0,70},{32,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(damper2.flange_b, fixed2.flange) annotation (Line( + points={{0,10},{30,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper3.flange_b, fixed3.flange) annotation (Line( + points={{0,-50},{30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+Demonstrate usage of damper components in different variants. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Damper; + + model Oscillator "Oscillator demonstrates the use of initial conditions." + + extends Modelica.Icons.Example; + + Translational.Components.Mass mass1( + L=1, + s(start=-0.5, fixed=true), + v(start=0, fixed=true), + m=1) annotation (Placement(transformation(extent={{-20,40},{0, + 60}}, rotation=0))); + Translational.Components.Spring spring1( s_rel0=1, c=10000) + annotation (Placement( + transformation(extent={{20,40},{40,60}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=1) + annotation (Placement(transformation( + extent={{60,40},{80,60}}, rotation=0))); + Translational.Sources.Force force1 + annotation (Placement(transformation(extent={{ + -60,40},{-40,60}}, rotation=0))); + Modelica.Blocks.Sources.Sine sine1(freqHz=15.9155) annotation (Placement(transformation( + extent={{-100,40},{-80,60}}, rotation=0))); + Translational.Components.Mass mass2( + L=1, + s(start=-0.5, fixed=true), + v(start=0, fixed=true), + m=1) annotation (Placement(transformation(extent={{-20,-60},{0, + -40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=1, c=10000) + annotation (Placement( + transformation(extent={{20,-60},{40,-40}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=1) + annotation (Placement(transformation( + extent={{60,-60},{80,-40}}, rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{ + -60,-60},{-40,-40}}, rotation=0))); + Modelica.Blocks.Sources.Sine sine2(freqHz=15.9155) annotation (Placement(transformation( + extent={{-100,-60},{-80,-40}}, rotation=0))); + Translational.Components.Damper damper1( d=10) + annotation (Placement(transformation( + extent={{20,-36},{40,-16}}, rotation=0))); + equation + connect(mass1.flange_b, spring1.flange_a) annotation (Line(points= + {{0,50},{20,50}}, color={0,191,0})); + connect(spring2.flange_a,damper1. flange_a) annotation (Line(points={{20, + -50},{20,-26}}, color={0,191,0})); + connect(mass2.flange_b, spring2.flange_a) annotation (Line(points= + {{0,-50},{20,-50}}, color={0,191,0})); + connect(damper1.flange_b,spring2. flange_b) annotation (Line(points={{40, + -26},{40,-50}}, color={0,191,0})); + connect(sine1.y,force1. f) annotation (Line(points={{-79,50},{-62,50}}, + color={0,0,127})); + connect(sine2.y,force2. f) annotation (Line(points={{-79,-50},{-62,-50}}, + color={0,0,127})); + connect(spring1.flange_b, fixed1.flange) annotation (Line( + points={{40,50},{70,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass2.flange_a) annotation (Line( + points={{-40,-50},{-20,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force1.flange, mass1.flange_a) annotation (Line( + points={{-40,50},{-20,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(spring2.flange_b, fixed2.flange) annotation (Line( + points={{40,-50},{70,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+A spring - mass system is a mechanical oscillator. If no +damping is included and the system is excited at resonance +frequency infinite amplitudes will result. +The resonant frequency is given by +omega_res = sqrt(c / m) +with: +

+ +
+      c spring stiffness
+      m mass
+
+ +

+To make sure that the system is initially at rest the initial +conditions s(start=0) and v(start=0) for the SlidingMass +are set. +If damping is added the amplitudes are bounded. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Oscillator; + + model Sensors "Sensors for translational systems." + import Modelica; + + extends Modelica.Icons.Example; + + Translational.Sensors.ForceSensor forceSensor annotation (Placement( + transformation(extent={{-34,40},{-14,60}}, + rotation=0))); + Translational.Sensors.SpeedSensor speedSensor1 annotation (Placement( + transformation(extent={{40,-40},{60,-20}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor1 annotation (Placement( + transformation(extent={{40,0},{60,20}}, rotation=0))); + Translational.Sensors.AccSensor accSensor1 annotation (Placement( + transformation(extent={{40,-80},{60,-60}}, rotation=0))); + Translational.Components.Mass mass(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{20,40},{40,60}}, rotation=0))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-64,40}, + {-44,60}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=10, freqHz=4) + annotation (Placement( + transformation(extent={{-100,40},{-80,60}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor2 annotation (Placement( + transformation(extent={{60,40},{80,60}}, rotation=0))); + Modelica.Mechanics.Translational.Sensors.MultiSensor multiSensor + annotation (Placement(transformation(extent={{-8,40},{12,60}}))); + equation + connect(sineForce.y, force.f) + annotation (Line(points={{-79,50},{-66,50}}, + color={0,0,127})); + connect(forceSensor.flange_a, force.flange) annotation (Line( + points={{-34,50},{-44,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, positionSensor1.flange) annotation (Line( + points={{20,50},{20,10},{40,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, speedSensor1.flange) annotation (Line( + points={{20,50},{20,-30},{40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, accSensor1.flange) annotation (Line( + points={{20,50},{20,-70},{40,-70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_b, positionSensor2.flange) annotation (Line( + points={{40,50},{60,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(forceSensor.flange_b, multiSensor.flange_a) annotation (Line( + points={{-14,50},{-8,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(multiSensor.flange_b, mass.flange_a) annotation (Line( + points={{12,50},{20,50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+These sensors measure +

+ +
+   force f in N
+   position s in m
+   velocity v in m/s
+   acceleration a in m/s2
+
+ +

+The measured velocity and acceleration is independent on +the flange the sensor is connected to. The position +depends on the flange (flange_a or flange_b) and the +length L of the component. +Plot PositionSensor1.s, PositionSensor2.s and SlidingMass1.s +to see the difference. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Sensors; + + model Friction "Use of model Stop" + extends Modelica.Icons.Example; + Modelica.Mechanics.Translational.Components.MassWithStopAndFriction stop1( + L=1, + s(fixed=true), + v(fixed=true), + smax=25, + smin=-25, + m=1, + F_prop=1, + F_Coulomb=5, + F_Stribeck=10, + fexp=2) annotation (Placement(transformation(extent={{20,60}, + {40,80}}, rotation=0))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-20,60}, + {0,80}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=25, freqHz=0.25) + annotation (Placement( + transformation(extent={{-60,60},{-40,80}}, + rotation=0))); + Modelica.Mechanics.Translational.Components.MassWithStopAndFriction stop2( + L=1, + smax=0.9, + smin=-0.9, + F_Coulomb=3, + F_Stribeck=5, + s(start=0, fixed=true), + m=1, + F_prop=1, + fexp=2, + v(start=-5, fixed=true)) + annotation (Placement(transformation(extent={{42,-60},{62, + -40}}, + rotation=0))); + Translational.Components.Spring spring(s_rel0=1, c=500) + annotation (Placement( + transformation(extent={{2,-60},{22,-40}}, + rotation=0))); + Translational.Components.Fixed fixed2(s0=-1.75) + annotation (Placement(transformation( + extent={{-40,-60},{-20,-40}}, + rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{-22,0}, + {-2,20}}, rotation=0))); + Components.Mass mass( + m=1, + L=1, + s(fixed=true), + v(fixed=true)) + annotation (Placement(transformation(extent={{10,0},{30,20}}))); + Components.SupportFriction supportFriction(f_pos= + Examples.Utilities.GenerateStribeckFrictionTable( + F_prop=1, + F_Coulomb=5, + F_Stribeck=10, + fexp=2, + v_max=12, + nTable=50)) + annotation (Placement(transformation(extent={{40,0},{60,20}}))); + equation + connect(spring.flange_b, stop2.flange_a) annotation (Line(points={{22,-50}, + {42,-50}},color={0,191,0})); + connect(sineForce.y, force.f) + annotation (Line(points={{-39,70},{-22,70}}, + color={0,0,127})); + connect(spring.flange_a, fixed2.flange) annotation (Line( + points={{2,-50},{-30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force.flange, stop1.flange_a) annotation (Line( + points={{0,70},{20,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass.flange_a) annotation (Line( + points={{-2,10},{10,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_b, supportFriction.flange_a) annotation (Line( + points={{30,10},{40,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sineForce.y, force2.f) annotation (Line( + points={{-39,70},{-30,70},{-30,10},{-24,10}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation ( + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-100,80},{-80,60}}, + textString="1)", + lineColor={0,0,255}), + Text( + extent={{-100,20},{-80,0}}, + textString="2)", + lineColor={0,0,255}), + Text( + extent={{-100,-40},{-80,-60}}, + lineColor={0,0,255}, + textString="3)")}), + Documentation(info=" +
    +
  1. Simulate and then plot stop1.f as a function of stop1.v + This gives the Stribeck curve.
  2. +
  3. The same model is also available by modeling the system with a Mass and + a SupportFriction model. The SupportFriction model defines the friction characteristic + with a table. The table is constructed with function + Examples.Utilities.GenerateStribeckFrictionTable(..) to generate the + same friction characteristic as with stop1. + The simulation results of stop1 and of model mass are therefore identical.
  4. +
  5. Model stop2 gives an example for a hard stop. However there + can arise some problems with the used modeling approach (use of + reinit(..), convergence problems). In this case use the ElastoGap + to model a stop (see example Preload).
  6. +
+"), + experiment(StopTime=5.0, Interval=0.001)); + end Friction; + + model PreLoad "Preload of a spool using ElastoGap models." + + extends Modelica.Icons.Example; + + Translational.Components.ElastoGap innerContactA( + c=1000e3, + d=250, + s_rel0=0.001) + annotation (Placement(transformation(extent={{-70,20},{-50,40}}, + rotation=0))); + Translational.Components.ElastoGap innerContactB( + c=1000e3, + d=250, + s_rel0=0.001) + annotation ( Placement( + transformation(extent={{50,20},{70,40}}, rotation=0))); + Translational.Components.Mass spool( + L=0.19, + m=0.150, + s(start=0.01475, fixed=true), + v(fixed=true)) annotation (Placement(transformation(extent={{0,-40}, + {40,0}}, rotation=0))); + Translational.Components.Fixed fixedLe( s0=-0.0955) + annotation (Placement( + transformation(extent={{-10,-10},{10,10}}, rotation=270, + origin={-80,90}))); + Translational.Components.Mass springPlateA( + m=10e-3, + L=0.002, + s(start=-0.093, fixed=true), + v(fixed=true)) annotation (Placement(transformation(extent={{-38,60}, + {-18,80}}, rotation=0))); + Translational.Components.Mass springPlateB( + m=10e-3, + s(start=-0.06925, fixed=true), + L=0.002, + v(fixed=true)) annotation ( + Placement(transformation(extent={{20,60},{40,80}}, rotation=0))); + Translational.Components.Spring spring( c=20e3, s_rel0=0.025) + annotation (Placement(transformation(extent={{-10,60},{10,80}},rotation= + 0))); + Translational.Components.ElastoGap outerContactA( + c=1000e3, + d=250, + s_rel0=0.0015) + annotation (Placement(transformation(extent={{-70,60},{-50,80}}, + rotation=0))); + Translational.Components.ElastoGap outerContactB( + c=1000e3, + d=250, + s_rel0=0.0015) annotation (Placement(transformation(extent={{50,60},{70, + 80}}, rotation=0))); + Translational.Components.Rod rod1( L=0.007) + annotation (Placement(transformation( + extent={{-40,30},{-20,50}}, rotation=0))); + Translational.Components.Damper friction( d=2500) + annotation (Placement( + transformation( + origin={-80,50}, + extent={{-10,-10},{10,10}}, + rotation=270))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-38,-30}, + {-18,-10}}, rotation=0))); + Translational.Components.Rod housing( L=0.0305) + annotation (Placement(transformation( + extent={{-10,80},{10,100}}, + rotation=0))); + Translational.Components.Rod rod3( L=0.00575) + annotation (Placement(transformation( + extent={{-40,-2},{-20,18}}, rotation=0))); + Translational.Components.Rod rod4( L=0.00575) + annotation (Placement(transformation( + extent={{20,-2},{40,18}}, rotation=0))); + Translational.Components.Rod rod2( L=0.007) + annotation (Placement(transformation( + extent={{20,30},{40,50}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=150, freqHz=0.01) + annotation (Placement(transformation(extent={{-78,-30},{-58,-10}}, + rotation=0))); + equation + connect(outerContactA.flange_b,springPlateA. flange_a) annotation (Line( + points={{-50,70},{-38,70}}, color={0,191,0})); + connect(springPlateA.flange_b,spring. flange_a) annotation (Line(points={{-18,70}, + {-18,70},{-10,70}},color={0,191,0})); + connect(spring.flange_b,springPlateB. flange_a) annotation (Line(points={{10,70}, + {20,70}}, color={0,191,0})); + connect(springPlateB.flange_b,outerContactB. flange_a) annotation (Line( + points={{40,70},{40,70},{50,70}}, + color={0,191,0})); + connect(outerContactB.flange_b,housing. flange_b) annotation (Line(points={{70,70}, + {70,90},{10,90}}, color={0,191,0})); + connect(springPlateA.flange_b,rod1. flange_a) annotation (Line(points={{-18,70}, + {-18,52},{-40,52},{-40,40}}, color={0,191,0})); + connect(innerContactA.flange_a,rod3. flange_a) annotation (Line(points={{-70,30}, + {-80,30},{-80,8},{-40,8}}, color={0,191,0})); + connect(innerContactA.flange_b,rod1. flange_b) annotation (Line(points={{-50,30}, + {-20,30},{-20,40}}, color={0,191,0})); + connect(rod2.flange_a,innerContactB. flange_a) annotation (Line(points={{20,40}, + {20,30},{50,30}}, color={0,191,0})); + connect(rod4.flange_b,innerContactB. flange_b) annotation (Line(points={{40,8},{ + 70,8},{70,30}}, color={0,191,0})); + connect(friction.flange_b,rod3. flange_a) annotation (Line(points={{-80,40}, + {-80,8},{-40,8}}, color={0,191,0})); + connect(rod3.flange_b,rod4. flange_a) annotation (Line(points={{-20,8},{ + 20,8}}, color={0,191,0})); + connect(rod2.flange_b,springPlateB. flange_a) annotation (Line(points={{40,40}, + {40,52},{20,52},{20,70}}, color={0,191,0})); + connect(spool.flange_a,rod4. flange_a) annotation (Line(points={{0,-20},{ + 0,8},{20,8}}, color={0,191,0})); + connect(sineForce.y, force.f) + annotation (Line(points={{-57,-20},{-46,-20},{ + -40,-20}}, + color={0,0,127})); + connect(force.flange, spool.flange_a) annotation (Line( + points={{-18,-20},{0,-20}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(outerContactA.flange_a, fixedLe.flange) annotation (Line( + points={{-70,70},{-80,70},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(housing.flange_a, fixedLe.flange) annotation (Line( + points={{-10,90},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(friction.flange_a, fixedLe.flange) annotation (Line( + points={{-80,60},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-92,-72},{90,-80}}, + textString="positive force => spool moves in positive direction ", + lineColor={0,0,255}), + Text( + extent={{-48,-52},{42,-60}}, + textString="Simulate for 100 s", + lineColor={0,0,255}), + Text( + extent={{-100,-62},{88,-70}}, + lineColor={0,0,255}, + textString="plot spool.s as a function of force.f")}), + Documentation(info=" +

+When designing hydraulic valves it is often necessary to hold the spool in +a certain position as long as an external force is below a threshold value. +If this force exceeds the threshold value a linear relation between force +and position is desired. +There are designs that need only one spring to accomplish this task. Using +the ElastoGap elements this design can be modelled easily. +Drawing of spool. +

+ +

+
+
+
+

+ +

+Spool position s as a function of working force f. +

+ +

+ +

+"), + experiment(StopTime=100, Interval=0.1)); + end PreLoad; + + model ElastoGap "Demonstrate usage of ElastoGap" + extends Modelica.Icons.Example; + Components.Fixed fixed + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Components.Rod rod1(L=2) + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); + Components.Rod rod2(L=2) + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + Components.SpringDamper springDamper1( + c=10, + s_rel0=1, + s_rel(fixed=false, start=1), + d=1.5) + annotation (Placement(transformation(extent={{-40,20},{-20,40}}))); + Components.SpringDamper springDamper2( + c=10, + s_rel0=1, + s_rel(fixed=false, start=1), + d=1.5) + annotation (Placement(transformation(extent={{20,20},{40,40}}))); + Components.Mass mass1( + s(fixed=true, start=2), + L=0, + m=1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-10,20},{10,40}}))); + Components.ElastoGap elastoGap1( + c=10, + s_rel(fixed=false, start=1.5), + s_rel0=1.5, + d=1.5) + annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); + Components.ElastoGap elastoGap2( + c=10, + s_rel(fixed=false, start=1.5), + s_rel0=1.5, + d=1.5) + annotation (Placement(transformation(extent={{20,-40},{40,-20}}))); + Components.Mass mass2( + s(fixed=true, start=2), + L=0, + m=1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-10,-40},{10,-20}}))); + parameter SI.TranslationalDampingConstant d=1.5 "Damping constant"; + equation + + connect(rod1.flange_b, fixed.flange) annotation (Line( + points={{-20,0},{0,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, rod2.flange_a) annotation (Line( + points={{0,0},{20,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_a, rod1.flange_a) annotation (Line( + points={{-40,30},{-48,30},{-48,0},{-40,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper2.flange_b, rod2.flange_b) annotation (Line( + points={{40,30},{50,30},{50,0},{40,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_b, mass1.flange_a) annotation (Line( + points={{-20,30},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass1.flange_b, springDamper2.flange_a) annotation (Line( + points={{10,30},{20,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_a, elastoGap1.flange_a) annotation (Line( + points={{-40,0},{-48,0},{-48,-30},{-40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod2.flange_b, elastoGap2.flange_b) annotation (Line( + points={{40,0},{50,0},{50,-30},{40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(elastoGap1.flange_b, mass2.flange_a) annotation (Line( + points={{-20,-30},{-10,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass2.flange_b, elastoGap2.flange_a) annotation (Line( + points={{10,-30},{20,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This model demonstrates the effect of ElastoGaps on eigenfrequency:
+Plot mass1.s and mass2.s as well as mass1.v and mass2.v

+mass1 is moved by both spring forces all the time.
+Since elastoGap1 lifts off at s > -0.5 m and elastoGap2 lifts off s < +0.5 m, +mass2 moves freely as long as -0.5 m < s < +0.5 m. +

+"), + experiment(StopTime=1.0, Interval=0.01)); + end ElastoGap; + + model Brake "Demonstrate braking of a translational moving mass" + extends Modelica.Icons.Example; + + Modelica.Mechanics.Translational.Components.Brake brake(fn_max=1, useSupport= + false) + annotation (Placement(transformation(extent={{6,40},{26,20}}))); + Modelica.Mechanics.Translational.Components.Mass mass1(m=1, + s(fixed=true), + v(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-34,20},{-14,40}}))); + Modelica.Blocks.Sources.Step step(startTime=0.1, height=2) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, + origin={-24,-10}))); + Modelica.Mechanics.Translational.Components.Brake brake1( + fn_max=1, useSupport= + true) + annotation (Placement(transformation(extent={{6,-60},{26,-40}}))); + Modelica.Mechanics.Translational.Components.Mass mass2(m=1, + s(fixed=true), + v(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-34,-60},{-14,-40}}))); + Modelica.Mechanics.Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{6,-80},{26,-60}}))); + equation + connect(mass1.flange_b, brake.flange_a) + annotation (Line( + points={{-14,30},{6,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(step.y, brake.f_normalized) annotation (Line( + points={{-13,-10},{16,-10},{16,19}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(mass2.flange_b, brake1.flange_a) + annotation (Line( + points={{-14,-50},{6,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(step.y, brake1.f_normalized) annotation (Line( + points={{-13,-10},{16,-10},{16,-39}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixed.flange, brake1.support) annotation (Line( + points={{16,-70},{16,-60}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( Documentation(info=" +

+This model consists of a mass with an initial velocity of 1 m/s. +After 0.1 s, a brake is activated and it is shown that the mass decelerates until +it arrives at rest and remains at rest. Two versions of this system are present, +one where the brake is implicitly grounded and one where it is explicitly grounded. +

+"), + experiment(StopTime=2.0, Interval=0.001)); + end Brake; + + model HeatLosses "Demonstrate the modeling of heat losses" + extends Modelica.Icons.Example; + Components.Mass mass1( + m=1, + s(fixed=true), + L=0.1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-60,20},{-40,40}}))); + Components.SpringDamper springDamper( + s_rel(fixed=true), + v_rel(fixed=true), + c=100, + d=10, + useHeatPort=true) + annotation (Placement(transformation(extent={{-30,20},{-10,40}}))); + Components.Damper damper(d=10, useHeatPort=true) + annotation (Placement(transformation(extent={{-10,10},{10,-10}}, + rotation=-90, + origin={-60,-10}))); + Components.ElastoGap elastoGap( + c=100, + d=20, + s_rel0=-0.02, + useHeatPort=true) + annotation (Placement(transformation(extent={{-90,-10},{-70,10}}))); + Components.Fixed fixed1 + annotation (Placement(transformation(extent={{-70,-40},{-50,-20}}))); + Sources.Force force + annotation (Placement(transformation(extent={{-90,20},{-70,40}}))); + Blocks.Sources.Sine sine1(freqHz=1, amplitude=20) + annotation (Placement(transformation(extent={{-120,20},{-100,40}}))); + Components.Mass mass2( + m=1, + L=0.1, + s(fixed=false), + v(fixed=false)) + annotation (Placement(transformation(extent={{0,20},{20,40}}))); + Components.SupportFriction supportFriction(useHeatPort=true) + annotation (Placement(transformation(extent={{30,20},{50,40}}))); + Components.Spring spring(c=100, s_rel(fixed=true)) + annotation (Placement(transformation(extent={{60,20},{80,40}}))); + Components.Mass mass3( + m=1, + L=0.1, + s(fixed=false), + v(fixed=true)) + annotation (Placement(transformation(extent={{90,20},{110,40}}))); + Components.Brake brake(fn_max=10, useHeatPort=true) + annotation (Placement(transformation(extent={{120,20},{140,40}}))); + Blocks.Sources.Sine sine2(amplitude=10, freqHz=2) + annotation (Placement(transformation(extent={{100,50},{120,70}}))); + Components.MassWithStopAndFriction massWithStopAndFriction( + L=0.1, + m=1, + F_prop=0.5, + F_Coulomb=1, + F_Stribeck=2, + fexp=2, + smin=0, + smax=0.4, + v(fixed=true), + useHeatPort=true) + annotation (Placement(transformation(extent={{180,20},{200,40}}))); + Thermal.HeatTransfer.Components.Convection convection + annotation (Placement(transformation(extent={{-10,-40},{10,-60}}))); + Blocks.Sources.Constant const(k=20) + annotation (Placement(transformation(extent={{-30,-90},{-10,-70}}))); + Thermal.HeatTransfer.Celsius.FixedTemperature TAmbient(T=25) + "Ambient temperature" + annotation (Placement(transformation(extent={{40,-60},{20,-40}}))); + Components.Fixed fixed2 + annotation (Placement(transformation(extent={{-120,-10},{-100,10}}))); + Components.SpringDamper springDamper1( + c=10000, + d=1000, + useHeatPort=true, + s_rel(fixed=true)) + annotation (Placement(transformation(extent={{150,20},{170,40}}))); + equation + + connect(mass1.flange_b, springDamper.flange_a) + annotation (Line( + points={{-40,30},{-30,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sine1.y, force.f) annotation (Line( + points={{-99,30},{-92,30}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(force.flange, mass1.flange_a) annotation (Line( + points={{-70,30},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass1.flange_a, damper.flange_a) annotation (Line( + points={{-60,30},{-60,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(damper.flange_b, fixed1.flange) annotation (Line( + points={{-60,-20},{-60,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper.flange_b, mass2.flange_a) annotation (Line( + points={{-10,30},{0,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass2.flange_b, supportFriction.flange_a) annotation (Line( + points={{20,30},{30,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(supportFriction.flange_b, spring.flange_a) annotation (Line( + points={{50,30},{60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(spring.flange_b, mass3.flange_a) annotation (Line( + points={{80,30},{90,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass3.flange_b, brake.flange_a) annotation (Line( + points={{110,30},{120,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sine2.y, brake.f_normalized) annotation (Line( + points={{121,60},{130,60},{130,41}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(elastoGap.flange_b, mass1.flange_a) annotation (Line( + points={{-70,0},{-60,0},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(const.y,convection. Gc) annotation (Line( + points={{-9,-80},{0,-80},{0,-60}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(TAmbient.port,convection. fluid) annotation (Line( + points={{20,-50},{10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(elastoGap.flange_a, fixed2.flange) annotation (Line( + points={{-90,0},{-110,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(elastoGap.heatPort, convection.solid) annotation (Line( + points={{-90,-10},{-90,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(damper.heatPort, convection.solid) annotation (Line( + points={{-50,0},{-50,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(springDamper.heatPort, convection.solid) annotation (Line( + points={{-30,20},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(supportFriction.heatPort, convection.solid) annotation (Line( + points={{30,20},{30,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(brake.heatPort, convection.solid) annotation (Line( + points={{120,20},{120,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(massWithStopAndFriction.heatPort, convection.solid) annotation ( + Line( + points={{180,20},{180,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(brake.flange_b, springDamper1.flange_a) annotation (Line( + points={{140,30},{150,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_b, massWithStopAndFriction.flange_a) + annotation (Line( + points={{170,30},{180,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.heatPort, convection.solid) annotation (Line( + points={{150,20},{150,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation ( Documentation(info=" +

+This model demonstrates how to model the dissipated power of a Translational model, +by enabling the heatPort of all components and connecting these heatPorts via +a convection element to the environment. The total heat flow generated by the +elements and transported to the environment +is present in variable convection.fluid. +

+"), + experiment(StopTime=2.0, Interval=0.001), + Diagram(coordinateSystem(extent={{-120,-100},{200,100}}, + preserveAspectRatio=false))); + end HeatLosses; + + package Utilities "Utility classes used by the Example models" + extends Modelica.Icons.UtilitiesPackage; + function GenerateStribeckFrictionTable + "Generate Stribeck friction table for example Friction for the SupportFriction" + extends Modelica.Icons.Function; + input Real F_prop(final unit="N.s/m", final min=0) + "Velocity dependent friction coefficient"; + input Modelica.SIunits.Force F_Coulomb + "Constant friction: Coulomb force"; + input Modelica.SIunits.Force F_Stribeck "Stribeck effect"; + input Real fexp(final unit="s/m", final min=0) "Exponential decay"; + input Real v_max "Generate table from v=0 ... v_max"; + input Integer nTable(min=2)=100 "Number of table points"; + output Real table[nTable,2] "Friction table"; + algorithm + for i in 1:nTable loop + table[i,1] :=v_max*(i - 1)/(nTable - 1); + table[i,2] :=F_Coulomb + F_prop*table[i, 1] + + F_Stribeck*exp(-fexp*table[i, 1]); + end for; + annotation (Documentation(info=" +

+Returns a table with the friction characteristic table[nTable,2] = [0, f1; ....; v_max, fn], where the first +column is the velocity v in the range 0..v_max and the second column is the friction force +according to the Stribeck curve: +

+
+  F_Coulomb + F_prop*v + F_Stribeck*exp(-fexp*v);
+
+ +")); + end GenerateStribeckFrictionTable; + annotation (Documentation(info=" +

Utility models and functions used in the Examples

+")); + end Utilities; + annotation ( + Documentation(info=" +

+This package contains example models to demonstrate the usage of the +Translational package. Open the models and +simulate them according to the provided description in the models. +

+ +")); + end Examples; + + package Components "Components for 1D translational mechanical drive trains" + extends Modelica.Icons.Package; + + model Fixed "Fixed flange" + parameter SI.Position s0=0 "Fixed offset position of housing"; + + Interfaces.Flange_b flange annotation (Placement(transformation( + origin={0,0}, + extent={{-10,10},{10,-10}}, + rotation=180))); + equation + flange.s = s0; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-80,-40},{80,-40}}, color={0,0,0}), + Line(points={{80,-40},{40,-80}}, color={0,0,0}), + Line(points={{40,-40},{0,-80}}, color={0,0,0}), + Line(points={{0,-40},{-40,-80}}, color={0,0,0}), + Line(points={{-40,-40},{-80,-80}}, color={0,0,0}), + Line(points={{0,-40},{0,-10}}, color={0,0,0}), + Text( + extent={{-150,-90},{150,-130}}, + textString="%name", + lineColor={0,0,255})}), + Documentation(info=" +

+The flange of a 1D translational mechanical system fixed +at an position s0 in the housing. May be used: +

+
    +
  • to connect a compliant element, such as a spring or a damper, + between a sliding mass and the housing. +
  • to fix a rigid element, such as a sliding mass, at a specific + position. +
+ +")); + end Fixed; + + model Mass "Sliding mass with inertia" + parameter SI.Mass m(min=0, start=1) "Mass of the sliding mass"; + parameter StateSelect stateSelect=StateSelect.default + "Priority to use s and v as states" annotation(Dialog(tab="Advanced")); + extends Translational.Interfaces.PartialRigid(L=0,s(start=0, stateSelect=stateSelect)); + SI.Velocity v(start=0, stateSelect=stateSelect) + "Absolute velocity of component"; + SI.Acceleration a(start=0) "Absolute acceleration of component"; + + equation + v = der(s); + a = der(v); + m*a = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+Sliding mass with inertia, without friction and two rigidly connected flanges. +

+

+The sliding mass has the length L, the position coordinate s is in the middle. +Sign convention: A positive force at flange flange_a moves the sliding mass in the positive direction. +A negative force at flange flange_a moves the sliding mass to the negative direction. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{55,0},{100,0}}, color={0,127,0}), + Rectangle( + extent={{-55,-30},{56,30}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Text( + extent={{-150,85},{150,45}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="m=%m")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{55,0},{100,0}}, color={0,127,0}), + Rectangle( + extent={{-55,-30},{55,30}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-44,-41},{51,-57}}, + textString="Length L", + lineColor={0,0,255}), + Line(points={{0,30},{0,53}}, color={0,0,0}), + Line(points={{-72,40},{1,40}}, color={0,0,0}), + Polygon( + points={{-7,42},{-7,38},{-1,40},{-7,42}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-61,53},{-9,42}}, + textString="Position s", + lineColor={0,0,255})})); + end Mass; + + model Rod "Rod without inertia" + extends Translational.Interfaces.PartialRigid; + + equation + 0 = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+Rod without inertia and two rigidly connected flanges. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{53,0},{99,0}}, color={0,127,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Rectangle( + extent={{-55,10},{53,-10}}, + lineColor={160,160,164}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-30},{150,-60}}, + lineColor={0,0,0}, + textString="L=%L")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{54,0},{100,0}}, color={0,127,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Rectangle( + extent={{-55,3},{53,-4}}, + lineColor={160,160,164}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-44,-41},{51,-57}}, + textString="Length L", + lineColor={0,0,255})})); + end Rod; + + model Spring "Linear 1D translational spring" + extends Translational.Interfaces.PartialCompliant; + parameter SI.TranslationalSpringConstant c(final min=0, start = 1) + "Spring constant"; + parameter SI.Distance s_rel0=0 "Unstretched spring length"; + + equation + f = c*(s_rel - s_rel0); + annotation ( + Documentation(info=" +

+A linear 1D translational spring. The component can be connected either +between two sliding masses, or between +a sliding mass and the housing (model Fixed), to describe +a coupling of the sliding mass with the housing via a spring. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-98,0},{-60,0},{-44,-30},{-16,30},{14,-30},{44,30},{ + 60,0},{100,0}},color={0,0,0}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="c=%c")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-100,65}}, color={128,128,128}), + Line(points={{100,0},{100,65}}, color={128,128,128}), + Line(points={{-100,60},{100,60}}, color={128,128,128}), + Polygon( + points={{90,63},{100,60},{90,57},{90,63}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-56,66},{36,81}}, + lineColor={0,0,255}, + textString="s_rel"), + Line(points={{-86,0},{-60,0},{-44,-30},{-16,30},{14,-30},{44,30},{ + 60,0},{84,0}}, color={0,0,0})})); + end Spring; + + model Damper "Linear 1D translational damper" + extends Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalDampingConstant d(final min=0, start = 0) + "Damping constant"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + equation + f = d*v_rel; + lossPower = f*v_rel; + annotation ( + Documentation(info=" +

+Linear, velocity dependent damper element. It can be either connected +between a sliding mass and the housing (model Fixed), or +between two sliding masses. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-90,0},{-60,0}}, color={0,0,0}), + Line(points={{-60,-30},{-60,30}}, color={0,0,0}), + Line(points={{-60,-30},{60,-30}}, color={0,0,0}), + Line(points={{-60,30},{60,30}}, color={0,0,0}), + Rectangle( + extent={{-60,30},{30,-30}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{30,0},{90,0}}, color={0,0,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="d=%d"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-20},{-14,-20}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-90,0},{-60,0}}, color={0,0,0}), + Line(points={{-60,-30},{-60,30}}, color={0,0,0}), + Line(points={{-60,-30},{60,-30}}, color={0,0,0}), + Line(points={{-60,30},{60,30}}, color={0,0,0}), + Rectangle( + extent={{-60,30},{30,-30}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{30,0},{90,0}}, color={0,0,0}), + Line(points={{-50,60},{50,60}}, color={128,128,128}), + Polygon( + points={{50,63},{60,60},{50,57},{50,63}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-58,68},{42,78}}, + lineColor={128,128,128}, + textString="der(s_rel)")})); + end Damper; + + model SpringDamper "Linear 1D translational spring and damper in parallel" + extends Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalSpringConstant c(final min=0, start = 1) + "Spring constant"; + parameter SI.TranslationalDampingConstant d(final min=0, start = 1) + "Damping constant"; + parameter SI.Position s_rel0=0 "Unstretched spring length"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + protected + Modelica.SIunits.Force f_c "Spring force"; + Modelica.SIunits.Force f_d "Damping force"; + equation + f_c = c*(s_rel - s_rel0); + f_d = d*v_rel; + f = f_c + f_d; + lossPower = f_d*v_rel; + annotation ( + Documentation(info=" +

+A spring and damper element connected in parallel. +The component can be +connected either between two sliding masses to describe the elasticity +and damping, or between a sliding mass and the housing (model Fixed), +to describe a coupling of the sliding mass with the housing via a spring/damper. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-80,40},{-60,40},{-45,10},{-15,70},{15,10},{45,70},{ + 60,40},{80,40}}, color={0,0,0}), + Line(points={{-80,40},{-80,-70}}, color={0,0,0}), + Line(points={{-80,-70},{-52,-70}}, color={0,0,0}), + Rectangle( + extent={{-52,-49},{38,-91}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-49},{68,-49}}, color={0,0,0}), + Line(points={{-51,-91},{69,-91}}, color={0,0,0}), + Line(points={{38,-70},{80,-70}}, color={0,0,0}), + Line(points={{80,40},{80,-70}}, color={0,0,0}), + Line(points={{-90,0},{-80,0}}, color={0,0,0}), + Line(points={{80,0},{90,0}}, color={0,0,0}), + Polygon( + points={{53,-18},{23,-8},{23,-28},{53,-18}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-57,-18},{23,-18}}, color={0,0,0}), + Text( + extent={{-150,120},{150,80}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-135},{150,-165}}, + lineColor={0,0,0}, + textString="d=%d"), + Text( + extent={{-150,-100},{150,-130}}, + lineColor={0,0,0}, + textString="c=%c"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-80},{-5,-80}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line( + points={{-80,32},{-58,32},{-43,2},{-13,62},{17,2},{47,62},{62,32}, + {80,32}}, + color={0,0,0}, + thickness=0.5), + Line(points={{-100,31},{-100,96}}, color={128,128,128}), + Line(points={{100,29},{100,94}}, color={128,128,128}), + Line(points={{-98,82},{100,82}}, color={128,128,128}), + Polygon( + points={{90,85},{100,82},{90,79},{90,85}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-63,83},{46,103}}, + lineColor={0,0,255}, + textString="s_rel"), + Rectangle( + extent={{-52,-28},{38,-72}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-51,-72},{69,-72}}, color={0,0,0}), + Line(points={{-52,-28},{68,-28}}, color={0,0,0}), + Line(points={{38,-50},{80,-50}}, color={0,0,0}), + Line(points={{-80,-50},{-52,-50}}, color={0,0,0}), + Line(points={{-80,32},{-80,-50}}, color={0,0,0}), + Line(points={{80,32},{80,-50}}, color={0,0,0}), + Line(points={{-90,0},{-80,0}}, color={0,0,0}), + Line(points={{90,0},{80,0}}, color={0,0,0})})); + end SpringDamper; + + model ElastoGap "1D translational spring damper combination with gap" + extends + Modelica.Mechanics.Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalSpringConstant c(final min=0, start=1) + "Spring constant"; + parameter SI.TranslationalDampingConstant d(final min=0, start=1) + "Damping constant"; + parameter SI.Position s_rel0=0 "Unstretched spring length"; + parameter Real n(final min=1) = 1 + "Exponent of spring force ( f_c = -c*|s_rel-s_rel0|^n )"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + + /* +Please note that initialization might fail due to the nonlinear spring characteristic +(spring force is zero for s_rel > s_rel0) +if a positive force is acting on the element and no other force balances this force +(e.g., when setting both initial velocity and acceleration to 0) +*/ + Boolean contact "=true, if contact, otherwise no contact"; + protected + Modelica.SIunits.Force f_c "Spring force"; + Modelica.SIunits.Force f_d2 "Linear damping force"; + Modelica.SIunits.Force f_d + "Linear damping force which is limited by spring force (|f_d| <= |f_c|)"; + equation + // Modify contact force, so that it is only "pushing" and not + // "pulling/sticking" and that it is continuous + contact = s_rel < s_rel0; + f_c = smooth(1, noEvent( if contact then -c*abs(s_rel - s_rel0)^n else 0)); + f_d2 = if contact then d*v_rel else 0; + f_d = smooth(0, noEvent( if contact then (if f_d2 < f_c then f_c else + if f_d2 > -f_c then -f_c else f_d2) else 0)); + f = f_c + f_d; + lossPower = f_d*v_rel; + annotation ( + Documentation(info=" +

+This component models a spring damper combination that can lift off. +It can be connected between a sliding mass and the housing (model +Fixed), +to describe the contact of a sliding mass with the housing. +

+ +

+As long as s_rel > s_rel0, no force is exerted (s_rel = flange_b.s - flange_a.s). +If s_rel ≤ s_rel0, the contact force is basically computed with a linear +spring/damper characteristic. With parameter n≥1 (exponent of spring force), +a nonlinear spring force can be modeled: +

+ +
+   desiredContactForce = c*|s_rel - s_rel0|^n + d*der(s_rel)
+
+ +

+Note, Hertzian contact is described by: +

+
    +
  • Contact between two metallic spheres: n=1.5
  • +
  • Contact between two metallic plates: n=1
  • +
+ +

+The above force law leads to the following difficulties: +

+ +
    +
  1. If the damper force becomes larger as the spring force and with opposite sign, + the contact force would be \"pulling/sticking\" which is unphysical, since during + contact only pushing forces can occur.
  2. + +
  3. When contact occurs with a non-zero relative speed (which is the usual + situation), the damping force has a non-zero value and therefore the contact + force changes discontinuously at s_rel = s_rel0. Again, this is not physical + because the force can only change continuously. (Note, this component is not an + idealized model where a steep characteristic is approximated by a discontinuity, + but it shall model the steep characteristic.)
  4. +
+ +

+In the literature there are several proposals to fix problem (2). Especially, often +the following model is used (see, e.g., +Lankarani, Nikravesh: Continuous Contact Force Models for Impact +Analysis in Multibody Systems, Nonlinear Dynamics 5, pp. 193-207, 1994, +pdf-download): +

+ +
+   f = c*s_rel^n + (d*s_rel^n)*der(s_rel)
+
+ +

+However, this and other models proposed in literature violate +issue (1), i.e., unphysical pulling forces can occur (if d*der(s_rel) +becomes large enough). Note, if the force law is of the form \"f = f_c + f_d\", then a +necessary condition is that |f_d| ≤ |f_c|, otherwise (1) and (2) are violated. +For this reason, the most simplest approach is used in the ElastoGap model +to fix both problems by using this necessary condition in the force law directly. +If s_rel0 = 0, the equations are: +

+ +
+    if s_rel ≥ 0 then
+       f = 0;    // contact force
+    else
+       f_c  = -c*|s_rel|^n;          // contact spring force (Hertzian contact force)
+       f_d2 = d*der(s_rel);         // linear contact damper force
+       f_d  = if f_d2 <  f_c then  f_c else
+              if f_d2 > -f_c then -f_c else f_d2;  // bounded damper force
+       f    = f_c + f_d;            // contact force
+    end if;
+
+ +

+Note, since |f_d| ≤ |f_c|, pulling forces cannot occur and the contact force +is always continuous, especially around the start of the penetration at s_rel = s_rel0. +

+ +

+In the next figure, a typical simulation with the ElastoGap model is shown +(Examples.ElastoGap) +where the different effects are visualized: +

+ +
    +
  1. Curve 1 (elastoGap1.f) is the unmodified contact force, i.e., the linear spring/damper + characteristic. A pulling/sticking force is present at the end of the contact.
  2. +
  3. Curve 2 (elastoGap2.f) is the contact force, where the force is explicitly set to + zero when pulling/sticking occurs. The contact force is discontinuous when contact starts.
  4. +
  5. Curve 3 (elastoGap3.f) is the ElastoGap model of this library. No discontinuity and no + pulling/sticking occurs.
  6. +
+ +

+ +

+"), Diagram(coordinateSystem( + preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-50,0}}, color={0,127,0}), + Line( + points={{-48,34},{-48,-46}}, + color={0,0,0}, + thickness=1), + Line(points={{8,40},{8,2}}, color={0,0,0}), + Line(points={{-2,0},{38,0},{38,44},{-2,44}}, color={0,0,0}), + Line(points={{38,22},{72,22}}, color={0,0,0}), + Line( + points={{-12,-38},{-12,20}}, + color={0,0,0}, + thickness=1), + Line(points={{-12,22},{8,22}}, color={0,0,0}), + Line(points={{-12,-38},{-2,-38}}, color={0,0,0}), + Line(points={{72,0},{100,0}}, color={0,127,0}), + Line(points={{72,22},{72,-42}}, color={0,0,0}), + Line(points={{-2,-38},{10,-28},{22,-48},{38,-28},{50,-48},{64,-28}, + {72,-40}}, color={0,0,0}), + Rectangle( + extent={{8,44},{38,0}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Text( + extent={{-64,-80},{64,-64}}, + lineColor={0,0,255}, + textString="s_rel"), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid)}), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-98,0},{-48,0}}, color={0,127,0}), + Line( + points={{-48,38},{-48,-38}}, + color={0,0,0}, + thickness=1), + Line(points={{8,-10},{8,-48}}, + color={0,0,0}), + Line(points={{-2,-50},{38,-50},{38,-6},{-2,-6}}, + color={0,0,0}), + Line(points={{38,-28},{72,-28}}, + color={0,0,0}), + Line( + points={{-12,-38},{-12,36}}, + color={0,0,0}, + thickness=1), + Line(points={{-12,-28},{8,-28}}, + color={0,0,0}), + Line(points={{-12,24},{-6,24}}, color={0,0,0}), + Line(points={{72,0},{98,0}}, color={0,127,0}), + Line(points={{72,22},{72,-42}}, color={0,0,0}), + Line(points={{-6,24},{6,34},{18,14},{34,34},{46,14},{60,34},{68,22}}, + color={0,0,0}), + Rectangle( + extent={{8,-6},{38,-50}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-70},{28,-70}}, color={0,0,0}), + Polygon( + points={{58,-70},{28,-60},{28,-80},{58,-70}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255}, + pattern=LinePattern.Dot), + Text( + extent={{-150,-125},{150,-95}}, + lineColor={0,0,0}, + textString="c=%c"), + Text( + extent={{-150,-160},{150,-130}}, + lineColor={0,0,0}, + textString="d=%d"), + Line(points={{68,22},{72,22}}, color={0,0,0}), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-44},{22,-44},{22,-28}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end ElastoGap; + + model SupportFriction "Coulomb friction in support" + + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryTwoFlangesAndSupport2; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + + parameter Real f_pos[:, 2]=[0, 1] + "[v, f] Positive sliding friction characteristic (v>=0)"; + parameter Real peak(final min=1) = 1 + "peak*f_pos[1,2] = Maximum friction force for v==0"; + extends Translational.Interfaces.PartialFriction; + + SI.Position s; + SI.Force f "Friction force"; + SI.Velocity v "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a "Absolute acceleration of flange_a and flange_b"; + equation + // Constant auxiliary variables + f0 = Modelica.Math.tempInterpol1(0, f_pos, 2); + f0_max = peak*f0; + free = false; + + s = flange_a.s - s_support; + flange_a.s = flange_b.s; + + // velocity and acceleration of flanges + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + + // Friction force + flange_a.f + flange_b.f - f = 0; + + // Friction force + f = if locked then sa*unitForce else + (if startForward then Modelica.Math.tempInterpol1( v, f_pos, 2) else + if startBackward then -Modelica.Math.tempInterpol1(-v, f_pos, 2) else + if pre(mode) == Forward then Modelica.Math.tempInterpol1( v, f_pos, 2) else + -Modelica.Math.tempInterpol1(-v, f_pos, 2)); + + lossPower = f*v_relfric; + annotation ( + Documentation(info=" +

+This element describes Coulomb friction in support, +i.e., a frictional force acting between a flange and the housing. +The positive sliding friction force \"f\" has to be defined +by table \"f_pos\" as function of the absolute velocity \"v\". +E.g. +

+
+       v |   f
+      ---+-----
+       0 |   0
+       1 |   2
+       2 |   5
+       3 |   8
+
+

+gives the following table: +

+
+   f_pos = [0, 0; 1, 2; 2, 5; 3, 8];
+
+

+Currently, only linear interpolation in the table is supported. +Outside of the table, extrapolation through the last +two table entries is used. It is assumed that the negative +sliding friction force has the same characteristic with negative +values. Friction is modelled in the following way: +

+

+When the absolute velocity \"v\" is not zero, the friction force +is a function of v and of a constant normal force. This dependency +is defined via table f_pos and can be determined by measurements, +e.g., by driving the gear with constant velocity and measuring the +needed driving force (= friction force). +

+

+When the absolute velocity becomes zero, the elements +connected by the friction element become stuck, i.e., the absolute +position remains constant. In this phase the friction force is +calculated from a force balance due to the requirement, that +the absolute acceleration shall be zero. The elements begin +to slide when the friction force exceeds a threshold value, +called the maximum static friction force, computed via: +

+
+   maximum_static_friction = peak * sliding_friction(v=0)  (peak >= 1)
+
+

+This procedure is implemented in a \"clean\" way by state events and +leads to continuous/discrete systems of equations if friction elements +are dynamically coupled which have to be solved by appropriate +numerical methods. The method is described in: +

+
+
Otter M., Elmqvist H., and Mattsson S.E. (1999): +
Hybrid Modeling in Modelica based on the Synchronous + Data Flow Principle. CACSD'99, Aug. 22.-26, Hawaii. +
+

+More precise friction models take into account the elasticity of the +material when the two elements are \"stuck\", as well as other effects, +like hysteresis. This has the advantage that the friction element can +be completely described by a differential equation without events. The +drawback is that the system becomes stiff (about 10-20 times slower +simulation) and that more material constants have to be supplied which +requires more sophisticated identification. For more details, see the +following references, especially (Armstrong and Canudas de Witt 1996): +

+
+
Armstrong B. (1991): +
Control of Machines with Friction. Kluwer Academic + Press, Boston MA.

+
Armstrong B., and Canudas de Wit C. (1996): +
Friction Modeling and Compensation. + The Control Handbook, edited by W.S.Levine, CRC Press, + pp. 1369-1382.

+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995): +
A new model for control of systems with friction. + IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.

+
+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={ + Rectangle( + extent={{-90,10},{90,-10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-48,-10},{-28,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{-10,-10},{10,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{30,-10},{50,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Polygon( + points={{-60,-30},{60,-30},{60,-12},{80,-12},{80,-50},{-80,-50},{ + -80,-12},{-60,-12},{-60,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Solid, + smooth=Smooth.None, + fillColor={175,175,175}), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-10,-85},{-5,-80}}, color={0,0,0}), + Line(points={{-5,-90},{5,-80}}, color={0,0,0}), + Line(points={{-10,-90},{0,-80}}, color={0,0,0}), + Line(points={{0,-90},{10,-80}}, color={0,0,0}), + Polygon( + points={{-60,-50},{-20,-80},{20,-80},{60,-50},{-60,-50}}, + lineColor={95,95,95}, + smooth=Smooth.None, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-50,30},{-30,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{-10,30},{10,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{30,30},{50,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Polygon( + points={{-60,30},{60,30},{60,12},{80,12},{80,50},{-80,50},{-80,12}, + {-60,12},{-60,30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Solid, + smooth=Smooth.None, + fillColor={175,175,175}), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-20},{0,-20}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end SupportFriction; + + model Brake "Brake based on Coulomb friction" + + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryTwoFlangesAndSupport2; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + parameter Real mue_pos[:, 2]=[0, 0.5] + "[v, f] Positive sliding friction characteristic (v>=0)"; + parameter Real peak(final min=1) = 1 + "peak*mue_pos[1,2] = Maximum friction force for v==0"; + parameter Real cgeo(final min=0) = 1 + "Geometry constant containing friction distribution assumption"; + parameter SI.Force fn_max(final min=0, start=1) "Maximum normal force"; + extends Translational.Interfaces.PartialFriction; + + SI.Position s; + SI.Force f "Brake friction force"; + SI.Velocity v "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a "Absolute acceleration of flange_a and flange_b"; + + Real mue0 "Friction coefficient for v=0 and forward sliding"; + SI.Force fn "Normal force (=fn_max*f_normalized)"; + + // Constant auxiliary variable + Modelica.Blocks.Interfaces.RealInput f_normalized + "Normalized force signal 0..1 (normal force = fn_max*f_normalized; brake is active if > 0)" + annotation (Placement(transformation( + origin={0,110}, + extent={{20,-20},{-20,20}}, + rotation=90))); + equation + mue0 = Modelica.Math.tempInterpol1(0, mue_pos, 2); + + s = s_a; + s = s_b; + + // velocity and acceleration of flanges flange_a and flange_b + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + + // Friction force, normal force and friction force for v_rel=0 + flange_a.f + flange_b.f - f = 0; + fn = fn_max*f_normalized; + f0 = mue0*cgeo*fn; + f0_max = peak*f0; + free = fn <= 0; + + // Friction force + f = if locked then sa*unitForce else + if free then 0 else + cgeo*fn*(if startForward then Modelica.Math.tempInterpol1( v, mue_pos, 2) else + if startBackward then -Modelica.Math.tempInterpol1(-v, mue_pos, 2) else + if pre(mode) == Forward then Modelica.Math.tempInterpol1( v, mue_pos, 2) else + -Modelica.Math.tempInterpol1(-v, mue_pos, 2)); + + lossPower = f*v_relfric; + annotation ( + Documentation(info=" +

+This component models a brake, i.e., a component where a frictional +force is acting between the housing and a flange and a controlled normal +force presses the flange to the housing in order to increase friction. +The normal force fn has to be provided as input signal f_normalized in a normalized form +(0 ≤ f_normalized ≤ 1), +fn = fn_max*f_normalized, where fn_max has to be provided as parameter. +Friction in the brake is modelled in the following way: +

+

+When the absolute velocity \"v\" is not zero, the friction force +is a function of the velocity dependent friction coefficient mue(v) , of +the normal force \"fn\", and of a geometry constant \"cgeo\" which takes into +account the geometry of the device and the assumptions on the friction +distributions: +

+
+        frictional_force = cgeo * mue(v) * fn
+
+

+ Typical values of coefficients of friction: +

+
+      dry operation   :  mue = 0.2 .. 0.4
+      operating in oil:  mue = 0.05 .. 0.1
+
+

+ The positive part of the friction characteristic mue(v), + v >= 0, is defined via table mue_pos (first column = v, + second column = mue). Currently, only linear interpolation in + the table is supported. +

+

+ When the absolute velocity becomes zero, the elements + connected by the friction element become stuck, i.e., the absolute + position remains constant. In this phase the friction force is + calculated from a force balance due to the requirement, that + the absolute acceleration shall be zero. The elements begin + to slide when the friction force exceeds a threshold value, + called the maximum static friction force, computed via: +

+
+       frictional_force = peak * cgeo * mue(w=0) * fn   (peak >= 1)
+
+

+This procedure is implemented in a \"clean\" way by state events and +leads to continuous/discrete systems of equations if friction elements +are dynamically coupled. The method is described in: +

+
+
Otter M., Elmqvist H., and Mattsson S.E. (1999): +
Hybrid Modeling in Modelica based on the Synchronous + Data Flow Principle. CACSD'99, Aug. 22.-26, Hawaii. +
+

+More precise friction models take into account the elasticity of the +material when the two elements are \"stuck\", as well as other effects, +like hysteresis. This has the advantage that the friction element can +be completely described by a differential equation without events. The +drawback is that the system becomes stiff (about 10-20 times slower +simulation) and that more material constants have to be supplied which +requires more sophisticated identification. For more details, see the +following references, especially (Armstrong and Canudas de Witt 1996): +

+
+
Armstrong B. (1991): +
Control of Machines with Friction. Kluwer Academic + Press, Boston MA.

+
Armstrong B., and Canudas de Wit C. (1996): +
Friction Modeling and Compensation. + The Control Handbook, edited by W.S.Levine, CRC Press, + pp. 1369-1382.

+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995): +
A new model for control of systems with friction. + IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.

+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={ + Rectangle( + extent={{-90,10},{90,-10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-20,30},{20,20}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-20,-20},{20,-30}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{0,-30},{10,-50},{-10,-50},{0,-30}}, + lineColor={0,0,127}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid), + Polygon( + points={{10,50},{-10,50},{0,30},{10,50}}, + lineColor={0,0,127}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid), + Line( + points={{0,90},{0,50}}, + color={0,0,0}, + smooth=Smooth.None), + Rectangle( + extent={{20,28},{30,22}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{20,-22},{30,-28}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{30,28},{36,-102}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{14,-96},{30,-102}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Line( + points={{0,-50},{0,-60},{-40,-50},{-40,48},{0,60},{0,90}}, + color={0,0,0}, + smooth=Smooth.None), + Text( + extent={{-150,-120},{150,-160}}, + textString="%name", + lineColor={0,0,255}), + Line(visible=useHeatPort, + points={{-100,-102},{-100,-16},{0,-16}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end Brake; + + model IdealGearR2T + "Gearbox transforming rotational into translational motion" + extends Modelica.Mechanics.Rotational.Components.IdealGearR2T; + annotation (Documentation(info=" +

Couples rotational and translational motion, like a toothed wheel with a toothed rack, specifying the ratio of rotational / translational motion.

+")); + end IdealGearR2T; + + model IdealRollingWheel + "Simple 1-dim. model of an ideal rolling wheel without inertia" + extends Modelica.Mechanics.Rotational.Components.IdealRollingWheel; + annotation (Documentation(info=" +

Couples rotational and translational motion, like an ideal rolling wheel, specifying the wheel radius.

+")); + end IdealRollingWheel; + + model InitializeFlange + "Initializes a flange with pre-defined position, speed and acceleration (usually, this is reference data from a control bus)" + extends Modelica.Blocks.Icons.Block; + parameter Boolean use_s_start = true + "= true, if initial position is defined by input s_start, otherwise not initialized"; + parameter Boolean use_v_start = true + "= true, if initial speed is defined by input v_start, otherwise not initialized"; + parameter Boolean use_a_start = true + "= true, if initial acceleration is defined by input a_start, otherwise not initialized"; + + parameter StateSelect stateSelect=StateSelect.default + "Priority to use flange angle and speed as states"; + + Modelica.Blocks.Interfaces.RealInput s_start(unit="m") if use_s_start + "Initial position of flange" + annotation (Placement(transformation(extent={{-140,40},{-100,80}}, + rotation=0))); + Modelica.Blocks.Interfaces.RealInput v_start(unit="m/s") if use_v_start + "Initial speed of flange" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + Modelica.Blocks.Interfaces.RealInput a_start(unit="m/s2") if use_a_start + "Initial angular acceleration of flange" + annotation (Placement(transformation(extent={{-140,-80},{-100,-40}}, + rotation=0))); + Interfaces.Flange_b flange "Flange that is initialized" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + + Modelica.SIunits.Position s_flange(stateSelect=stateSelect)=flange.s + "Flange position"; + Modelica.SIunits.Velocity v_flange(stateSelect=stateSelect)= der(s_flange) + "= der(s_flange)"; + + protected + encapsulated model Set_s_start "Set s_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput s_start(unit="m") "Start position" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + initial equation + flange.s = s_start; + equation + flange.f = 0; + + end Set_s_start; + + encapsulated model Set_v_start "Set v_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput v_start(unit="m/s") "Start velocity" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + initial equation + der(flange.s) = v_start; + equation + flange.f = 0; + + end Set_v_start; + + encapsulated model Set_a_start "Set a_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput a_start(unit="m/s2") "Start acceleration" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange(s(stateSelect=StateSelect.avoid)) + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.SIunits.Velocity v = der(flange.s) annotation(HideResult=true); + initial equation + der(v) = a_start; + equation + flange.f = 0; + + end Set_a_start; + + encapsulated model Set_flange_f "Set flange_f to zero" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + equation + flange.f = 0; + end Set_flange_f; + protected + Set_s_start set_s_start if use_s_start annotation (Placement( + transformation(extent={{-20,50},{0,70}}, rotation=0))); + Set_v_start set_v_start if use_v_start + annotation (Placement(transformation(extent={{-20, + -10},{0,10}}, rotation=0))); + Set_a_start set_a_start if use_a_start + annotation (Placement(transformation(extent={{-20, + -70},{0,-50}}, rotation=0))); + Set_flange_f set_flange_f annotation (Placement(transformation(extent={ + {20,-100},{40,-80}}, rotation=0))); + equation + connect(set_s_start.flange, flange) annotation (Line( + points={{0,60},{60,60},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_v_start.flange, flange) annotation (Line( + points={{0,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_a_start.flange, flange) annotation (Line( + points={{0,-60},{60,-60},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_flange_f.flange, flange) annotation (Line( + points={{40,-90},{60,-90},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(s_start, set_s_start.s_start) annotation (Line( + points={{-120,60},{-22,60}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(v_start, set_v_start.v_start) annotation (Line( + points={{-120,0},{-22,0}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(a_start, set_a_start.a_start) annotation (Line( + points={{-120,-60},{-22,-60}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={ + Text( + extent={{-94,74},{68,46}}, + lineColor={0,0,0}, + textString="s_start"), + Text( + extent={{-94,16},{70,-14}}, + lineColor={0,0,0}, + textString="v_start"), + Text( + extent={{-94,-46},{66,-74}}, + lineColor={0,0,0}, + textString="a_start")}), + Documentation(info=" +

+This component is used to optionally initialize the position, speed, +and/or acceleration of the flange to which this component +is connected. Via parameters use_s_start, use_v_start, use_a_start +the corresponding input signals s_start, v_start, a_start are conditionally +activated. If an input is activated, the corresponding flange property +is initialized with the input value at start time. +

+ +

+For example, if \"use_s_start = true\", then flange.s is initialized +with the value of the input signal \"s_start\" at the start time. +

+ +

+Additionally, it is optionally possible to define the \"StateSelect\" +attribute of the flange position and the flange speed via parameter +\"stateSelection\". +

+ +

+This component is especially useful when the initial values of a flange +shall be set according to reference signals of a controller that are +provided via a signal bus. +

+ +")); + end InitializeFlange; + + model MassWithStopAndFriction + "Sliding mass with hard stop and Stribeck friction" + extends PartialFrictionWithStop; + SI.Velocity v(start=0, stateSelect = StateSelect.always) + "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a(start=0) + "Absolute acceleration of flange_a and flange_b"; + parameter Modelica.SIunits.Mass m(start=1) "Mass"; + parameter Real F_prop(final unit="N.s/m", final min=0, start = 1) + "Velocity dependent friction"; + parameter Modelica.SIunits.Force F_Coulomb(start=5) + "Constant friction: Coulomb force"; + parameter Modelica.SIunits.Force F_Stribeck(start=10) "Stribeck effect"; + parameter Real fexp(final unit="s/m", final min=0, start = 2) + "Exponential decay"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + Integer stopped; + encapsulated partial model PartialFrictionWithStop + "Base model of Coulomb friction elements with stop" + + import SI = Modelica.SIunits; + import Modelica.Mechanics.Translational.Interfaces.PartialRigid; + parameter SI.Position smax(start= 25) + "Right stop for (right end of) sliding mass"; + parameter SI.Position smin(start=-25) + "Left stop for (left end of) sliding mass"; + parameter SI.Velocity v_small=1e-3 + "Relative velocity near to zero (see model info text)" + annotation(Dialog(tab="Advanced")); + // Equations to define the following variables have to be defined in subclasses + SI.Velocity v_relfric "Relative velocity between frictional surfaces"; + SI.Acceleration a_relfric + "Relative acceleration between frictional surfaces"; + SI.Force f + "Friction force (positive, if directed in opposite direction of v_rel)"; + SI.Force f0 "Friction force for v=0 and forward sliding"; + SI.Force f0_max "Maximum friction force for v=0 and locked"; + Boolean free "true, if frictional element is not active"; + // Equations to define the following variables are given in this class + Real sa(unit="1") + "Path parameter of friction characteristic f = f(a_relfric)"; + Boolean startForward(start=false, fixed=true) + "= true, if v_rel=0 and start of forward sliding or v_rel > v_small"; + Boolean startBackward(start=false, fixed=true) + "= true, if v_rel=0 and start of backward sliding or v_rel < -v_small"; + Boolean locked(start=false) "true, if v_rel=0 and not sliding"; + extends PartialRigid(s(start=0, stateSelect = StateSelect.always)); + constant Integer Unknown=3 "Value of mode is not known"; + constant Integer Free=2 "Element is not active"; + constant Integer Forward=1 "v_rel > 0 (forward sliding)"; + constant Integer Stuck=0 + "v_rel = 0 (forward sliding, locked or backward sliding)"; + constant Integer Backward=-1 "v_rel < 0 (backward sliding)"; + Integer mode( + final min=Backward, + final max=Unknown, + start=Unknown, fixed=true); + protected + constant SI.Acceleration unitAcceleration = 1 annotation(HideResult=true); + constant SI.Force unitForce = 1 annotation(HideResult=true); + equation + /* Friction characteristic + (locked is introduced to help the Modelica translator determining + the different structural configurations, + if for each configuration special code shall be generated) +*/ + startForward = pre(mode) == Stuck and (sa > f0_max/unitForce and s < (smax - L/2) or + pre(startForward) and sa > f0/unitForce and s < (smax - L/2)) or pre(mode) + == Backward and v_relfric > v_small or initial() and (v_relfric > 0); + startBackward = pre(mode) == Stuck and (sa < -f0_max/unitForce and s > (smin + L/2) or + pre(startBackward) and sa < -f0/unitForce and s > (smin + L/2)) or pre(mode) + == Forward and v_relfric < -v_small or initial() and (v_relfric < 0); + locked = not free and + not (pre(mode) == Forward or startForward or pre(mode) == Backward or startBackward); + + a_relfric/unitAcceleration = if locked then 0 else + if free then sa else + if startForward then sa - f0_max/unitForce else + if startBackward then sa + f0_max/unitForce else + if pre(mode) == Forward then sa - f0_max/unitForce else + sa + f0_max/unitForce; + + /* Friction torque has to be defined in a subclass. Example for a clutch: + f = if locked then sa else + if free then 0 else + cgeo*fn*(if startForward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + if startBackward then -Math.tempInterpol1(-v_relfric, mue_pos, 2) else + if pre(mode) == Forward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + -Math.tempInterpol1(-v_relfric, mue_pos, 2)); +*/ + // finite state machine to determine configuration + mode = if free then Free else + (if (pre(mode) == Forward or pre(mode) == Free or startForward) and v_relfric > 0 and s < (smax - L/2) then + Forward else + if (pre(mode) == Backward or pre(mode) == Free or startBackward) and v_relfric < 0 and s > (smin + L/2) then + Backward else + Stuck); + annotation (Documentation(info=" +

+Basic model for Coulomb friction that models the stuck phase in a reliable way.
+Additionally, a left and right stop are handled. +

+")); + end PartialFrictionWithStop; + equation + // Constant auxiliary variables + f0 = (F_Coulomb + F_Stribeck); + f0_max = f0*1.001; + free = f0 <= 0 and F_prop <= 0 and s > smin + L/2 and s < smax - L/2; + // Velocity and acceleration of flanges + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + // Equilibrium of forces + 0 = flange_a.f + flange_b.f - f - m*der(v); + // Friction force + f = if locked then sa*unitForce else + if free then 0 else + (if startForward then F_prop*v + F_Coulomb + F_Stribeck else + if startBackward then F_prop*v - F_Coulomb - F_Stribeck else + if pre(mode) == Forward then F_prop*v + F_Coulomb + F_Stribeck*exp(-fexp*abs(v)) else + F_prop*v - F_Coulomb - F_Stribeck*exp(-fexp*abs(v))); + lossPower = f*v_relfric; + equation + when (initial()) then + assert(s > smin + L/2 or s >= smin + L/2 and v >= 0, + "Error in initialization of hard stop. (s - L/2) must be >= smin\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smin=" + String(smin) + ")"); + assert(s < smax - L/2 or s <= smax - L/2 and v <= 0, + "Error in initialization of hard stop. (s + L/2) must be <= smax\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smax=" + String(smax) + ")"); + end when; + + // Define events for hard stops and reinitialize the state variables velocity v and position s + stopped = if s <= smin + L/2 then -1 else if s >= smax - L/2 then +1 else 0; + when stopped <> 0 then + reinit(s, if stopped < 0 then smin + L/2 else smax - L/2); + reinit(v, 0); + end when; + /* +Version 1: + + when not (s < smax - L/2) then + reinit(s, smax - L/2); + if (not initial() or v>0) then + reinit(v, 0); + end if; + end when; + + when not (s > smin + L/2) then + reinit(s, smin + L/2); + if (not initial() or v<0) then + reinit(v, 0); + end if; + end when; + +Version 2: + stopped := if s <= smin + L/2 then -1 else if s >= smax - L/2 then +1 else 0; + when (initial()) then + assert(s > smin + L/2 or s >= smin + L/2 and v >= 0, + "Error in initialization of hard stop. (s - L/2) must be >= smin\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smin=" + String(smin) + ")"); + assert(s < smax - L/2 or s <= smax - L/2 and v <= 0, + "Error in initialization of hard stop. (s + L/2) must be <= smax\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smax=" + String(smax) + ")"); + end when; + when stopped <> 0 then + reinit(s, if stopped < 0 then smin + L/2 else smax - L/2); + if (not initial() or stopped*v>0) then + reinit(v, 0); + end if; + end when; +*/ + annotation ( + Documentation(info=" +

This element describes the Stribeck friction characteristics of a sliding mass, +i. e. the frictional force acting between the sliding mass and the support. Included is a +hard stop for the position.

+

+The surface is fixed and there is friction between sliding mass and surface. +The frictional force f is given for positive velocity v by: +

+
+f = F_Coulomb + F_prop * v + F_Stribeck * exp (-fexp * v)
+
+ +

+ +

+ +

+The distance between the left and the right connector is given by parameter L. +The position of the center of gravity, coordinate s, is in the middle between +the two flanges.

+

+There are hard stops at smax and smin, i. e. if +flange_a.s >= smin and flange_b.s <= xmax the sliding mass can move freely.

+

When the absolute velocity becomes zero, the sliding mass becomes stuck, i.e., the absolute position remains constant. In this phase the +friction force is calculated from a force balance due to the requirement that the +absolute acceleration shall be zero. The elements begin to slide when the friction +force exceeds a threshold value, called the maximum static friction force, computed via:

+
+   maximum_static_friction =  F_Coulomb + F_Stribeck
+
+

+ This requires the states Stop.s and Stop.v . If these states are eliminated during the index reduction +the model will not work. To avoid this any inertias should be connected via springs +to the Stop element, other sliding masses, dampers or hydraulic chambers must be avoided.

+

For more details of the used friction model see the following reference:

+ +
+
Beater P. (1999):
+
+Entwurf hydraulischer Maschinen. Springer Verlag Berlin Heidelberg New York.
+
+ +

The friction model is implemented in a \"clean\" way by state events and leads to +continuous/discrete systems of equations which have to be solved by appropriate +numerical methods. The method is described in:

+ +
+
Otter M., Elmqvist H., and Mattsson S.E. (1999):
+
Hybrid Modeling in Modelica based on the Synchronous Data Flow Principle. + CACSD'99, Aug. 22.-26, Hawaii.
+
+ +

More precise friction models take into account the elasticity of the material when +the two elements are \"stuck\", as well as other effects, like hysteresis. This has +the advantage that the friction element can be completely described by a differential +equation without events. The drawback is that the system becomes stiff (about 10-20 times +slower simulation) and that more material constants have to be supplied which requires more +sophisticated identification. For more details, see the following references, especially +(Armstrong and Canudas de Witt 1996):

+
+
+Armstrong B. (1991):
+
Control of Machines with Friction. Kluwer Academic Press, Boston MA.
+
+
Armstrong B., and Canudas de Wit C. (1996):
+
Friction Modeling and Compensation. The Control Handbook, edited by W.S.Levine, CRC Press, pp. 1369-1382.
+
+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995):
+
A new model for control of systems with friction. IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.
+
+
+ +

Optional heatPort

+

+The dissipated energy is transported in form of heat to the optional heatPort connector +that can be enabled via parameter \"useHeatPort\". Independently whether the heatPort is +or is not enabled, the dissipated power is defined with variable \"lossPower\". +If contact occurs at the hard stops, the lossPower is not correctly modelled +at this time instant, because the hard stop would introduce a Dirac impulse +in the lossPower due to the discontinuously changing kinetic energy of the mass +(lossPower is the derivative of the kinetic energy at the time instant of the impact). +

+ +", revisions=" +

Release Notes:

+
    +
  • First Version from December 7, 1999 by P. Beater (based on Rotational.BearingFriction)
  • +
  • July 14, 2001 by P. Beater, assert on initialization added, diagram modified
  • +
  • October 11, 2001, by Hans Olsson, Dassault Systèmes AB, modified assert to handle start at stops, +modified event logic such if you have friction parameters equal to zero you do not get events +between the stops.
  • +
  • June 10, 2002 by P. Beater, StateSelect.always for variables s and v (instead of fixed=true).
  • +
+"), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{80,-100},{50,-90},{50,-110},{80,-100}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-30,-100},{50,-100}}, color={0,0,0}), + Rectangle( + extent={{-30,30},{35,-35}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Line(points={{-90,0},{-30,0}}, color={0,127,0}), + Rectangle( + extent={{-70,-45},{74,-60}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-63,-15},{-55,-45}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{60,-16},{69,-45}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{35,0},{90,0}}, color={0,127,0}), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-50,-90},{-30,-70}}, color={0,0,0}), + Line(points={{-30,-70},{30,-70}}, color={0,0,0}), + Line(points={{-30,-90},{-10,-70}}, color={0,0,0}), + Line(points={{-10,-90},{10,-70}}, color={0,0,0}), + Line(points={{10,-90},{30,-70}}, color={0,0,0}), + Text( + extent={{-150,-110},{150,-140}}, + lineColor={0,0,0}, + textString="m=%m"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-40},{3,-40}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{50,-75},{20,-65},{20,-85},{50,-75}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-75},{20,-75}}, color={0,0,0}), + Rectangle( + extent={{-30,26},{35,-9}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Line(points={{-90,0},{-30,0}}, color={0,127,0}), + Line(points={{35,0},{90,0}}, color={0,127,0}), + Rectangle( + extent={{-68,-14},{76,-29}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-119,43},{-111,17}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{-111,43},{-111,50}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-151,49},{-113,49}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-149,51},{-126,60}}, + textString="s min", + lineColor={0,0,255}), + Polygon( + points={{-121,52},{-111,49},{-121,46},{-121,52}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{124,42},{132,17}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{124,39},{124,87}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-19,78},{121,78}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-17,83},{6,92}}, + textString="s max", + lineColor={0,0,255}), + Polygon( + points={{114,81},{124,78},{114,75},{114,81}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{5,26},{5,63}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-77,58},{-1,58}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-75,60},{-38,71}}, + textString="Position s", + lineColor={0,0,255}), + Polygon( + points={{-5,61},{5,58},{-5,55},{-5,61}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-10},{-100,-60}}, color={0,0,0}), + Line(points={{100,-10},{100,-60}}, color={0,0,0}), + Polygon( + points={{90,-47},{100,-50},{90,-53},{90,-47}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{-90,-47},{-90,-53},{-100,-50},{-90,-47}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{-90,-50},{92,-50}}, color={0,0,0}), + Text( + extent={{-11,-46},{26,-36}}, + textString="Length L", + lineColor={0,0,255})})); + end MassWithStopAndFriction; + + model RelativeStates "Definition of relative state variables" + extends Translational.Interfaces.PartialTwoFlanges; + parameter StateSelect stateSelect=StateSelect.prefer + "Priority to use the relative angle and relative speed as states"; + SI.Position s_rel(start=0, stateSelect=StateSelect.prefer) + "Relative position used as state variable"; + SI.Velocity v_rel(start=0, stateSelect=StateSelect.prefer) + "Relative velocity used as state variable"; + SI.Acceleration a_rel(start=0) "Relative angular acceleration"; + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + a_rel = der(v_rel); + flange_a.f = 0; + flange_b.f = 0; + annotation ( + Documentation(info=" +

+Usually, the absolute position and the absolute velocity of +Modelica.Mechanics.Translational.Inertia models are used as state variables. +In some circumstances, relative quantities are better suited, e.g., +because it may be easier to supply initial values. +In such cases, model RelativeStates allows the definition of state variables +in the following way: +

+
    +
  • Connect an instance of this model between two flange connectors.
  • +
  • The relative position and the relative velocity + between the two connectors are used as state variables. +
+

+An example is given in the next figure +

+ +

+\"relativeStates2\" +

+ +

+Here, the relative position and the relative velocity between +the two masses are used as state variables. Additionally, the +simulator selects either the absolute position and absolute +velocity of model mass1 or of model mass2 as state variables. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Ellipse( + extent={{-40,40},{40,-40}}, + lineColor={0,255,255}, + fillColor={0,255,255}, + fillPattern=FillPattern.Solid), + Text( + extent={{-40,40},{40,-40}}, + textString="S", + lineColor={0,0,255}), + Line( + points={{-92,0},{-42,0}}, + color={0,0,0}, + pattern=LinePattern.Dot), + Line( + points={{40,0},{90,0}}, + color={0,0,0}, + pattern=LinePattern.Dot), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Ellipse( + extent={{-40,40},{40,-40}}, + lineColor={0,255,255}, + fillColor={0,255,255}, + fillPattern=FillPattern.Solid), + Text( + extent={{-40,40},{40,-40}}, + textString="S", + lineColor={0,0,255}), + Line( + points={{40,0},{90,0}}, + color={0,0,0}, + pattern=LinePattern.Dash), + Line(points={{-100,-10},{-100,-80}}, color={160,160,164}), + Line(points={{100,-10},{100,-80}}, color={160,160,164}), + Polygon( + points={{80,-65},{80,-55},{100,-60},{80,-65}}, + lineColor={160,160,164}, + fillColor={160,160,164}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-60},{80,-60}}, color={160,160,164}), + Text( + extent={{-30,-70},{30,-90}}, + textString="w_rel", + lineColor={0,0,255}), + Line(points={{-76,80},{-5,80}}, color={128,128,128}), + Polygon( + points={{14,80},{-6,85},{-6,75},{14,80}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{18,87},{86,74}}, + lineColor={128,128,128}, + textString="moving direction"), + Line( + points={{-90,0},{-40,0}}, + color={0,0,0}, + pattern=LinePattern.Dash)})); + end RelativeStates; + annotation (Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100,-100},{100,100}}), graphics = { + Rectangle( + origin = {11.5,31.183}, + lineColor = {64,64,64}, + fillColor = {255,255,255}, + fillPattern = FillPattern.Sphere, + extent = {{-67,-66},{44,-6}})}), Documentation(info=" +

+This package contains basic components 1D mechanical translational drive trains. +

+")); + end Components; + + package Sensors "Sensors for 1-dim. translational mechanical quantities" + + extends Modelica.Icons.SensorsPackage; + + model PositionSensor "Ideal sensor to measure the absolute position" + extends Translational.Interfaces.PartialAbsoluteSensor; + Modelica.Blocks.Interfaces.RealOutput s(unit="m") + "Absolute position of flange as output signal" + annotation (Placement(transformation(extent={{100,-11}, + {120,9}}, rotation=0), iconTransformation(extent={{100, + -10},{120,10}}))); + + equation + s = flange.s; + annotation ( + Documentation(info=" +

+Measures the absolute position s of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{114,-62}}, + lineColor={0,0,0}, + textString="s")})); + end PositionSensor; + + model SpeedSensor "Ideal sensor to measure the absolute velocity" + extends Translational.Interfaces.PartialAbsoluteSensor; + Modelica.Blocks.Interfaces.RealOutput v(unit="m/s") + "Absolute velocity of flange as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + + equation + v = der(flange.s); + annotation ( + Documentation(info=" +

+Measures the absolute velocity v of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{111,-61}}, + lineColor={0,0,0}, + textString="v")})); + end SpeedSensor; + + model AccSensor "Ideal sensor to measure the absolute acceleration" + extends Translational.Interfaces.PartialAbsoluteSensor; + SI.Velocity v "Absolute velocity of flange"; + Modelica.Blocks.Interfaces.RealOutput a(unit="m/s2") + "Absolute acceleration of flange as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + + equation + v = der(flange.s); + a = der(v); + annotation ( + Documentation(info=" +

+Measures the absolute acceleration a +of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{115,-60}}, + lineColor={0,0,0}, + textString="a")})); + end AccSensor; + + model RelPositionSensor "Ideal sensor to measure the relative position" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput s_rel(unit="m") + "Distance between two flanges (= flange_b.s - flange_a.s) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative position s of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{8,-68},{42,-102}}, + lineColor={0,0,0}, + textString="s"), + Line(points={{0,-99},{0,-60}}, color={0,0,127})})); + end RelPositionSensor; + + model RelSpeedSensor "Ideal sensor to measure the relative speed" + extends Translational.Interfaces.PartialRelativeSensor; + SI.Position s_rel + "Distance between the two flanges (flange_b.s - flange_a.s)"; + Modelica.Blocks.Interfaces.RealOutput v_rel(unit="m/s") + "Relative velocity between two flanges (= der(flange_b.s) - der(flange_a.s)) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative speed v of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +", revisions= + " +

Release Notes:

+
    +
  • First Version from August 26, 1999 by P. Beater
  • +
+"), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{8,-68},{42,-102}}, + lineColor={0,0,0}, + textString="v"), + Line(points={{0,-100},{0,-61}}, color={0,0,127})})); + end RelSpeedSensor; + + model RelAccSensor "Ideal sensor to measure the relative acceleration" + extends Translational.Interfaces.PartialRelativeSensor; + SI.Position s_rel + "Distance between the two flanges (flange_b.s - flange_a.s)"; + SI.Velocity v_rel + "Relative velocity between the two flanges (der(flange_b.s) - der(flange_a.s))"; + Modelica.Blocks.Interfaces.RealOutput a_rel(unit="m/s2") + "Relative acceleration between two flanges (= der(v_rel)) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + a_rel = der(v_rel); + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative acceleration a of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{7,-68},{41,-102}}, + lineColor={0,0,0}, + textString="a"), + Line(points={{0,-99},{0,-60}}, color={0,0,127})})); + end RelAccSensor; + + model ForceSensor "Ideal sensor to measure the force between two flanges" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput f(unit="N") + "Force in flange_a and flange_b (f = flange_a.f = -flange_b.f) as output signal" + annotation (Placement(transformation( + origin={-80,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + equation + flange_a.s = flange_b.s; + flange_a.f = f; + annotation ( + Documentation(info=" +

+Measures the cut-force between two flanges in an ideal way +and provides the result as output signal (to be further processed +with blocks of the Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-40,-70},{40,-120}}, + lineColor={0,0,0}, + textString="f"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-80,-100},{-80,0}}, color={0,0,127})})); + end ForceSensor; + + model PowerSensor + "Ideal sensor to measure the power between two flanges (= flange_a.f*der(flange_a.s))" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput power(unit="W") + "Power in flange flange_a as output signal" + annotation (Placement(transformation( + origin={-80,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + equation + flange_a.s = flange_b.s; + power = flange_a.f*der(flange_a.s); + annotation ( + Documentation(info=" +

+Measures the power between two flanges in an ideal way +and provides the result as output signal power +(to be further processed with blocks of the Modelica.Blocks library). +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-75,-79},{67,-119}}, + lineColor={0,0,0}, + textString="power"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-80,-100},{-80,0}}, color={0,0,127})})); + end PowerSensor; + + model MultiSensor + "Ideal sensor to measure the absolute velocity, force and power between two flanges" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput power(unit="W") + "Power in flange flange_a as output signal" + annotation (Placement(transformation( + origin={-60,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + Modelica.Blocks.Interfaces.RealOutput f(unit="N") + "Force in flange_a and flange_b (f = flange_a.f = -flange_b.f) as output signal" + annotation (Placement(transformation( + extent={{10,-10},{-10,10}}, + rotation=90, + origin={0,-110}))); + Modelica.Blocks.Interfaces.RealOutput v(unit="m/s") + "Absolute velocity of flange as output signal as output signal" + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=-90, + origin={60,-110}))); + equation + flange_a.s = flange_b.s; + f = flange_a.f; + v = der(flange_a.s); + power = f*v; + + annotation ( + Documentation(info=" +

+Measures the absolute velocity of a flange_a, the cut-force and power between two flanges in an +ideal way and provides the results as output signals v, f and power, respectively.

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-146,-70},{-56,-100}}, + lineColor={0,0,0}, + textString="power"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-60,-100},{-60,-60}}, + color={0,0,127}), + Text( + extent={{-28,-71},{52,-101}}, + lineColor={0,0,0}, + textString="f"), + Line(points={{0,-100},{0,-60}}, color={0,0,127}), + Line(points={{60,-100},{60,-60}}, color={0,0,127}), + Text( + extent={{60,-70},{114,-101}}, + lineColor={0,0,0}, + textString="v")})); + end MultiSensor; + annotation ( + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100, + 100}}), graphics={ + Line(points={{-56,-61},{-56,-81}}, color={0,0,0}), + Line(points={{-36,-61},{-36,-81}}, color={0,0,0}), + Line(points={{-16,-61},{-16,-81}}, color={0,0,0}), + Line(points={{4,-61},{4,-81}}, color={0,0,0}), + Line(points={{24,-61},{24,-81}}, color={0,0,0}), + Line(points={{44,-61},{44,-81}}, color={0,0,0})}), + Documentation(info=" +

+This package contains ideal sensor components that provide +the connector variables as signals for further processing with the +Modelica.Blocks library. +

+")); + end Sensors; + + package Sources "Sources to drive 1D translational mechanical components" + extends Modelica.Icons.SourcesPackage; + + model Position + "Forced movement of a flange according to a reference position" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + ( s(stateSelect=if exact then StateSelect.default else StateSelect.prefer)); + parameter Boolean exact=false + "true/false exact treatment/filtering the input signal"; + parameter SI.Frequency f_crit=50 + "if exact=false, critical frequency of filter to filter input signal" annotation(Dialog(enable=not exact)); + SI.Velocity v(start=0, stateSelect=if exact then StateSelect.default else StateSelect.prefer) + "If exact=false, absolute velocity of flange_b else dummy"; + SI.Acceleration a(start=0) + "If exact=false, absolute acceleration of flange_b else dummy"; + Modelica.Blocks.Interfaces.RealInput s_ref(unit="m") + "Reference position of flange as input signal" annotation (Placement( + transformation(extent={{-140,-20},{-100,20}}, rotation=0))); + protected + parameter Modelica.SIunits.AngularFrequency w_crit=2*Modelica.Constants.pi*f_crit + "Critical frequency"; + constant Real af=1.3617 "s coefficient of Bessel filter"; + constant Real bf=0.6180 "s*s coefficient of Bessel filter"; + + initial equation + if not exact then + s = s_ref; + end if; + equation + if exact then + s = s_ref; + v = 0; + a = 0; + else + // Filter: a = s_ref*S^2/(1 + (af/w_crit)*S + (bf/w_crit^2)*S^2) + v = der(s); + a = der(v); + a = ((s_ref - s)*w_crit - af*v)*(w_crit/bf); + end if; + annotation ( + Documentation(info=" +

+The input signal s_ref defines the reference +position in [m]. Flange flange_b is forced +to move relative to the support connector according to this reference motion. According to parameter +exact (default = false), this is done in the following way: +

    +
  1. exact=true
    + The reference position is treated exactly. This is only possible, if + the input signal is defined by an analytical function which can be + differentiated at least twice. If this prerequisite is fulfilled, + the Modelica translator will differentiate the input signal twice + in order to compute the reference acceleration of the flange.
  2. +
  3. exact=false
    + The reference position is filtered and the second derivative + of the filtered curve is used to compute the reference acceleration + of the flange. This second derivative is not computed by + numerical differentiation but by an appropriate realization of the + filter. For filtering, a second order Bessel filter is used. + The critical frequency (also called cut-off frequency) of the + filter is defined via parameter f_crit in [Hz]. This value + should be selected in such a way that it is higher as the essential + low frequencies in the signal.
  4. +
+

+The input signal can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-56,-36},{-178,-66}}, + lineColor={0,0,0}, + textString="s_ref"), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Text( + extent={{144,-30},{30,-60}}, + lineColor={0,0,0}, + textString="exact="), + Text( + extent={{134,-68},{22,-96}}, + lineColor={0,0,0}, + textString="%exact")})); + end Position; + + model Speed "Forced movement of a flange according to a reference speed" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + ( s(start=0, fixed=true, stateSelect=StateSelect.prefer)); + parameter Boolean exact=false + "true/false exact treatment/filtering the input signal"; + parameter SI.Frequency f_crit=50 + "if exact=false, critical frequency of filter to filter input signal" annotation(Dialog(enable=not exact)); + SI.Velocity v(stateSelect=if exact then StateSelect.default else StateSelect.prefer) + "Absolute velocity of flange_b"; + SI.Acceleration a + "If exact=false, absolute acceleration of flange_b else dummy"; + Modelica.Blocks.Interfaces.RealInput v_ref(unit="m/s") + "Reference speed of flange as input signal" annotation (Placement( + transformation(extent={{-140,-20},{-100,20}}, rotation=0))); + + protected + parameter Modelica.SIunits.AngularFrequency w_crit=2*Modelica.Constants.pi*f_crit + "Critical frequency"; + initial equation + if not exact then + v = v_ref; + end if; + equation + v = der(s); + if exact then + v = v_ref; + a = 0; + else + // Filter: a = v_ref/(1 + (1/w_crit)*s) + a = der(v); + a = (v_ref - v)*w_crit; + end if; + annotation ( + Documentation(info=" +

+The input signal v_ref defines the reference +speed in [m/s]. Flange flange_b is forced +to move relative to the support connector according to this reference motion. According to parameter +exact (default = false), this is done in the following way: +

    +
  1. exact=true
    + The reference speed is treated exactly. This is only possible, if + the input signal is defined by an analytical function which can be + differentiated at least once. If this prerequisite is fulfilled, + the Modelica translator will differentiate the input signal once + in order to compute the reference acceleration of the flange.
  2. +
  3. exact=false
    + The reference speed is filtered and the first derivative + of the filtered curve is used to compute the reference acceleration + of the flange. This first derivative is not computed by + numerical differentiation but by an appropriate realization of the + filter. For filtering, a first order filter is used. + The critical frequency (also called cut-off frequency) of the + filter is defined via parameter f_crit in [Hz]. This value + should be selected in such a way that it is higher as the essential + low frequencies in the signal.
  4. +
+

+The input signal can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-54,-36},{-174,-68}}, + lineColor={0,0,0}, + textString="v_ref"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{146,-38},{32,-64}}, + lineColor={0,0,0}, + textString="exact="), + Text( + extent={{140,-76},{22,-102}}, + lineColor={0,0,0}, + textString="%exact")})); + end Speed; + + model Accelerate + "Forced movement of a flange according to an acceleration signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + (s(start=0, fixed=true, stateSelect=StateSelect.prefer)); + SI.Velocity v(start=0, fixed=true, stateSelect=StateSelect.prefer) + "Absolute velocity of flange_b"; + SI.Acceleration a "Absolute acceleration of flange_b"; + + Modelica.Blocks.Interfaces.RealInput a_ref(unit="m/s2") + "Absolute acceleration of flange as input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + + equation + v = der(s); + a = der(v); + a = a_ref; + annotation ( + Documentation(info=" +

+The input signal a in [m/s2] moves the 1D translational flange +connector flange_b with a predefined acceleration, i.e., the flange +is forced to move relative to the support connector with this acceleration. The velocity and the +position of the flange are also predefined and are determined by +integration of the acceleration. +

+

+The acceleration \"a(t)\" can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-56,-40},{-166,-68}}, + lineColor={0,0,0}, + textString="a_ref"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255})})); + end Accelerate; + + model Move + "Forced movement of a flange according to a position, velocity and acceleration signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2; + Modelica.Blocks.Interfaces.RealInput u[3] + "Position, velocity and acceleration of flange as input signals" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + protected + function position + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + output Real q; + algorithm + q :=q_qd_qdd[1]; + annotation (derivative(noDerivative=q_qd_qdd) = position_der, + InlineAfterIndexReduction=true); + end position; + + function position_der + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + input Real dummy_der; + output Real qd; + algorithm + qd :=q_qd_qdd[2]; + annotation (derivative(noDerivative=q_qd_qdd, order=2) = position_der2, + InlineAfterIndexReduction=true); + end position_der; + + function position_der2 + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + input Real dummy_der; + input Real dummy_der2; + output Real qdd; + algorithm + qdd :=q_qd_qdd[3]; + end position_der2; + equation + s = position(u,time); + annotation ( + Documentation(info=" +

+Flange flange_b is forced to move relative to the support connector with a predefined motion +according to the input signals: +

+
+    u[1]: position of flange
+    u[2]: velocity of flange
+    u[3]: acceleration of flange
+
+

+The user has to guarantee that the input signals are consistent to each other, +i.e., that u[2] is the derivative of u[1] and that +u[3] is the derivative of u. There are, however, +also applications where by purpose these conditions do not hold. For example, +if only the position dependent terms of a mechanical system shall be +calculated, one may provide position = position(t) and set the velocity +and the acceleration to zero. +

+

+The input signals can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-192,-38},{-32,-70}}, + lineColor={0,0,0}, + textString="s,v,a"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255})})); + end Move; + + model Force + "External force acting on a drive train element as input signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2; + Modelica.Blocks.Interfaces.RealInput f(unit="N") "Driving force as input signal" + annotation (Placement(transformation( + extent={{-140,-20},{-100,20}}, rotation=0))); + + equation + flange.f = -f; + annotation ( + Documentation(info=" +

+The input signal \"f\" in [N] characterizes an external +force which acts (with positive sign) at a flange, +i.e., the component connected to the flange is driven by force f. +

+

+Input signal f can be provided from one of the signal generator +blocks of Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{-100,10},{20,10},{20,41},{90,0},{20,-41},{20,-10},{-100, + -10},{-100,10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,-32},{-80,-62}}, + lineColor={0,0,0}, + textString="f"), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-30,-60},{30,-60}}, color={0,0,0}), + Line(points={{0,-60},{0,-101}}, color={0,0,0}), + Line(points={{-30,-80},{-10,-60}}, color={0,0,0}), + Line(points={{-10,-80},{10,-60}}, color={0,0,0}), + Line(points={{10,-80},{30,-60}}, color={0,0,0}), + Polygon( + points={{-61,-50},{-30,-40},{-30,-60},{-61,-50}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-31,-50},{50,-50}}, color={0,0,0}), + Line(points={{-50,-80},{-30,-60}}, color={0,0,0})})); + end Force; + + model Force2 "Input signal acting as torque on two flanges" + extends Translational.Interfaces.PartialTwoFlanges; + Modelica.Blocks.Interfaces.RealInput f(unit="N") "Driving force as input signal" + annotation (Placement(transformation( + extent={{-20,-20},{20,20}}, rotation=270, + origin={0,60}), iconTransformation( + extent={{-20,-20},{20,20}}, + rotation=270, + origin={0,40}))); + + equation + flange_a.f = f; + flange_b.f = -f; + annotation ( + Documentation(info=" +

+The input signal \"f\" in [N] characterizes an external +force which acts (with positive sign) at both flanges, +i.e., the components connected to these flanges are driven by force f. +

+

+Input signal s can be provided from one of the signal generator +blocks of Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-150,-40},{150,-80}}, + textString="%name", + lineColor={0,0,255}), + Polygon( + points={{90,0},{60,-30},{60,-10},{10,-10},{10,10},{60,10},{60,31}, + {90,0}}, + lineColor={0,127,0}, + smooth=Smooth.None, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Polygon( + points={{-90,0},{-60,30},{-60,10},{-10,10},{-10,-10},{-60,-10},{-60, + -30},{-90,0}}, + lineColor={0,127,0}, + smooth=Smooth.None, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid)})); + end Force2; + + model LinearSpeedDependentForce "Linear dependency of force versus speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_nominal + "Nominal force (if negative, force is acting as load)"; + parameter Boolean ForceDirection=true + "Same direction of force in both directions of movement"; + parameter Modelica.SIunits.Velocity v_nominal(min=Modelica.Constants.eps) + "Nominal speed"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + + equation + v = der(s); + if ForceDirection then + f = -f_nominal*abs(v/v_nominal); + else + f = -f_nominal*(v/v_nominal); + end if; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-100,-100},{100,100}}, + color={0,0,255})}), Documentation(info=" +

+Model of force, linearly dependent on velocity of flange.
+Parameter ForceDirection chooses whether direction of force is the same in both directions of movement or not. +

+")); + end LinearSpeedDependentForce; + + model QuadraticSpeedDependentForce + "Quadratic dependency of force versus speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_nominal + "Nominal force (if negative, force is acting as load)"; + parameter Boolean ForceDirection=true + "Same direction of force in both directions of movement"; + parameter Modelica.SIunits.Velocity v_nominal(min=Modelica.Constants.eps) + "Nominal speed"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + equation + v = der(s); + if ForceDirection then + f = -f_nominal*(v/v_nominal)^2; + else + f = -f_nominal*smooth(1, if v >= 0 then (v/v_nominal)^2 else -(v/v_nominal)^2); + end if; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,-100},{-80,-98},{-60,-92},{-40,-82},{-20,-68},{0,-50},{20,-28},{40,-2},{60,28},{80,62},{100,100}}, + color={0,0,127}, + smooth=Smooth.Bezier)}),Documentation(info=" +

+Model of force, quadratic dependent on velocity of flange.
+Parameter ForceDirection chooses whether direction of force is the same in both directions of movement or not. +

+")); + end QuadraticSpeedDependentForce; + + model ConstantForce "Constant force, not dependent on speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_constant + "Nominal force (if negative, force is acting as load)"; + equation + f = -f_constant; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-100,0},{98,0}}, + color={0,0,255}), Text( + extent={{-118,58},{126,34}}, + lineColor={0,0,0}, + textString="%f_constant")}), + Documentation(info=" +

+Model of constant force, not dependent on velocity of flange.
+Positive force acts accelerating. +

+")); + end ConstantForce; + + model ConstantSpeed "Constant speed, not dependent on force" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Velocity v_fixed + "Fixed speed (if negative, force is acting as load)"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + equation + v = der(s); + v = v_fixed; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{0,-100},{0,100}}, + color={0,0,255}), Text( + extent={{-120,60},{124,36}}, + lineColor={0,0,0}, + textString="%v_fixed")}), + Documentation(info=" +

+Model of fixed velocity of flange, not dependent on force. +

+")); + end ConstantSpeed; + + model ForceStep "Constant force, not dependent on speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force stepForce(start=1) + "Height of force step (if negative, force is acting as load)"; + parameter Modelica.SIunits.Force offsetForce(start=0) "Offset of force"; + parameter Modelica.SIunits.Time startTime=0 + "Force = offset for time < startTime"; + equation + f = -offsetForce - (if time < startTime then 0 else stepForce); + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-80,-60},{0,-60},{0, + 60},{80,60}}, color={0,0,255}), Text( + extent={{0,-40},{100,-60}}, + lineColor={0,0,0}, + textString="time")}), Documentation(info=" +

+Model of a force step at time .
+Positive force acts accelerating. +

+")); + end ForceStep; + + annotation ( Documentation(info=" +

+This package contains ideal sources to drive 1D mechanical translational drive trains. +

+")); + end Sources; + + package Interfaces + "Interfaces for 1-dim. translational mechanical components" + extends Modelica.Icons.InterfacesPackage; + + connector Flange_a + "(left) 1D translational flange (flange axis directed INTO cut plane, e. g. from left to right)" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation(defaultComponentName = "flange_a", + Documentation(info=" +

+This is a flange for 1D translational mechanical systems. In the cut plane of +the flange a unit vector n, called flange axis, is defined which is directed +INTO the cut plane, i. e. from left to right. All vectors in the cut plane are +resolved with respect to +this unit vector. E.g. force f characterizes a vector which is directed in +the direction of n with value equal to f. When this flange is connected to +other 1D translational flanges, this means that the axes vectors of the connected +flanges are identical. +

+

+The following variables are transported through this connector: +

+
+  s: Absolute position of the flange in [m]. A positive translation
+     means that the flange is translated along the flange axis.
+  f: Cut-force in direction of the flange axis in [N].
+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), + Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, + {100,100}}), graphics={Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid), Text( + extent={{-160,110},{40,50}}, + lineColor={0,127,0}, + textString="%name")})); + end Flange_a; + + connector Flange_b + "(right) 1D translational flange (flange axis directed OUT OF cut plane)" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation(defaultComponentName = "flange_b", + Documentation(info=" +

+This is a flange for 1D translational mechanical systems. In the cut plane of +the flange a unit vector n, called flange axis, is defined which is directed +OUT OF the cut plane. All vectors in the cut plane are resolved with respect to +this unit vector. E.g. force f characterizes a vector which is directed in +the direction of n with value equal to f. When this flange is connected to +other 1D translational flanges, this means that the axes vectors of the connected +flanges are identical. +

+

+The following variables are transported through this connector: +

+  s: Absolute position of the flange in [m]. A positive translation
+     means that the flange is translated along the flange axis.
+  f: Cut-force in direction of the flange axis in [N].
+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), Text( + extent={{-40,110},{160,50}}, + lineColor={0,127,0}, + textString="%name")})); + end Flange_b; + + connector Support "Support/housing 1D translational flange" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={ + Rectangle( + extent={{-60,60},{60,-60}}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), + Text( + extent={{-160,110},{40,50}}, + lineColor={0,127,0}, + textString="%name"), + Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), Icon(coordinateSystem( + preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={Rectangle( + extent={{-150,150},{150,-150}}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), Rectangle( + extent={{-90,-90},{90,90}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), + Documentation(info=" +

This is a connector for 1-dim. rotational mechanical systems and models the support or housing of a shaft. The following variables are defined in this connector:

+ + + + + + + + +

s

Absolute position of the support/housing in [m]

f

Reaction force in the support/housing in [N]

+


The support connector is usually defined as conditional connector. It is most convenient to utilize it

+ +")); + end Support; + + model InternalSupport + "Adapter model to utilize conditional support connector" + input SI.Force f + "External support force (must be computed via force balance in model where InternalSupport is used; = flange.f)"; + SI.Position s "External support position (= flange.s)"; + Flange_a flange + "Internal support flange (must be connected to the conditional support connector for useSupport=true and to conditional fixed model for useSupport=false)" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + equation + flange.f = f; + flange.s = s; + annotation ( Icon(coordinateSystem( + preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={Text( + extent={{-200,80},{200,40}}, + lineColor={0,0,255}, + textString="%name"), Rectangle( + extent={{-20,20},{20,-20}}, + lineColor={0,127,0}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid)}), + Documentation(info=" +

+This is an adapter model to utilize a conditional support connector +in an elementary component, i.e., where the component equations are +defined textually: +

+ +
    +
  • If useSupport = true, the flange has to be connected to the conditional + support connector.
  • +
  • If useSupport = false, the flange has to be connected to the conditional + fixed model.
  • +
+ +

+Variable f is defined as input and must be provided when using +this component as a modifier (computed via a force balance in +the model where InternalSupport is used). Usually, model InternalSupport is +utilized via the partial models: +

+ +
+ +PartialElementaryOneFlangeAndSupport,
+ +PartialElementaryTwoFlangesAndSupport,
+ +PartialElementaryRotationalToTranslational. +
+ +

+Note, the support position can always be accessed as internalSupport.s, and +the support force can always be accessed as internalSupport.f. +

+")); + end InternalSupport; + + partial model PartialTwoFlanges + "Component with two translational 1D flanges" + + Flange_a flange_a + "(left) driving flange (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b + "(right) driven flange (flange axis directed out of cut plane)" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + annotation ( + Documentation(info=" +

+This is a 1D translational component with two flanges. +It is used e.g., to built up parts of a drive train consisting +of several base components. +

+")); + end PartialTwoFlanges; + + partial model PartialOneFlangeAndSupport + "Partial model for a component with one translational 1-dim. shaft flange and a support used for graphical modeling, i.e., the model is build up by drag-and-drop from elementary components" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Support internalSupport + "Internal support/housing of component (either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-3,-83},{3,-77}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-94},{30,-74}}))); + equation + connect(fixed.flange, internalSupport) annotation (Line( + points={{20,-84},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(internalSupport, support) annotation (Line( + points={{0,-80},{0,-100}}, + pattern=LinePattern.None, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used e.g., to build up parts of a drive train graphically consisting +of several components. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{21,-95},{61,-96}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialOneFlangeAndSupport; + + partial model PartialTwoFlangesAndSupport + "Partial model for a component with two translational 1-dim. shaft flanges and a support used for graphical modeling, i.e., the model is build up by drag-and-drop from elementary components" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left end" + annotation (Placement(transformation(extent={{-110,-10}, {-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right end" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Support internalSupport + "Internal support/housing of component (either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-3,-83},{3,-77}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + equation + connect(fixed.flange, internalSupport) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(internalSupport, support) annotation (Line( + points={{0,-80},{0,-100}}, + pattern=LinePattern.None, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with two flanges and a support/housing. +It is used e.g., to build up parts of a drive train graphically consisting +of several components. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialTwoFlangesAndSupport; + + partial model PartialRigid + "Rigid connection of two translational 1D flanges" + SI.Position s + "Absolute position of center of component (s = flange_a.s + L/2 = flange_b.s - L/2)"; + parameter SI.Length L(start=0) + "Length of component, from left flange to right flange (= flange_b.s - flange_a.s)"; + Flange_a flange_a "Left flange of translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b "Right flange of translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + equation + flange_a.s = s - L/2; + flange_b.s = s + L/2; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with two rigidly connected flanges. +The fixed distance between the left and the right flange is defined by parameter \"L\". +The forces at the right and left flange can be different. +It is used e.g., to built up sliding masses. +

+")); + end PartialRigid; + + partial model PartialCompliant + "Compliant connection of two translational 1D flanges" + + Flange_a flange_a + "Left flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b + "Right flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + SI.Position s_rel(start=0) + "Relative distance (= flange_b.s - flange_a.s)"; + SI.Force f + "Force between flanges (positive in direction of flange axis R)"; + + equation + s_rel = flange_b.s - flange_a.s; + flange_b.f = f; + flange_a.f = -f; + annotation ( + Documentation(info=" +

+This is a 1D translational component with a compliant connection of two +translational 1D flanges where inertial effects between the two +flanges are not included. The absolute value of the force at the left and the right +flange is the same. It is used to built up springs, dampers etc. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), Line(points={{-60,-90},{20,-90}}, + color={0,0,0})})); + end PartialCompliant; + + partial model PartialCompliantWithRelativeStates + "Base model for the compliant connection of two translational 1-dim. shaft flanges where the relative position and relative velocities are used as states" + + parameter StateSelect stateSelect=StateSelect.prefer + "Priority to use phi_rel and w_rel as states" + annotation(HideResult=true, Dialog(tab="Advanced")); + parameter SI.Distance s_nominal=1e-4 + "Nominal value of s_rel (used for scaling)" annotation(Dialog(tab="Advanced")); + + SI.Position s_rel(start=0, stateSelect=stateSelect, nominal=s_nominal) + "Relative distance (= flange_b.s - flange_a.s)"; + SI.Velocity v_rel(start=0, stateSelect=stateSelect) + "Relative velocity (= der(s_rel))"; + + SI.Force f "Forces between flanges (= flange_b.f)"; + Translational.Interfaces.Flange_a flange_a + "Left flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Translational.Interfaces.Flange_b flange_b + "Right flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + flange_b.f = f; + flange_a.f = -f; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with a compliant connection of two +translational 1-dim. flanges where inertial effects between the two +flanges are neglected. The basic assumption is that the cut-forces +of the two flanges sum-up to zero, i.e., they have the same absolute value +but opposite sign: flange_a.f + flange_b.f = 0. This base class +is used to built up force elements such as springs, dampers, friction. +

+ +

+The difference to base class \"PartialCompliant\" is that the relative +distance and the relative velocity are defined as preferred states. +The reason is that for a large class of drive trains, +the absolute position is quickly increasing during operation. +Numerically, it is better to use relative distances between drive train components +because they remain in a limited size. For this reason, StateSelect.prefer +is set for the relative distance of this component. +

+ +

+In order to improve the numerics, a nominal value for the relative distance +should be set, since drive train distances are in a small order and +then step size control of the integrator is practically switched off for +such a variable. A default nominal value of s_nominal = 1e-4 is defined. +This nominal value might also be computed from other values, such +as \"s_nominal = f_nominal / c\" for a spring, if f_nominal +and c have more meaningful values for the user. +

+ +")); + end PartialCompliantWithRelativeStates; + + partial model PartialElementaryOneFlangeAndSupport + "Obsolete partial model. Use PartialElementaryOneFlangeAndSupport2." + extends Modelica.Icons.ObsoleteModel; + + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Modelica.SIunits.Length s + "Distance between flange and support (= flange.s - support.s)"; + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + protected + InternalSupport internalSupport(f=-flange.f) + "Internal support/housing of component as a model with connector flange (flange is either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + public + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + equation + s = flange.s - internalSupport.s; + connect(internalSupport.flange, support) annotation (Line( + points={{0,-80},{0,-100}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, internalSupport.flange) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used to build up elementary components of a drive train with +equations in the text layer. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryOneFlangeAndSupport; + + partial model PartialElementaryOneFlangeAndSupport2 + "Partial model for a component with one translational 1-dim. shaft flange and a support used for textual modeling, i.e., for elementary models" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Modelica.SIunits.Length s + "Distance between flange and support (= flange.s - support.s)"; + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + Support support(s=s_support, f=-flange.f) if useSupport + "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Modelica.SIunits.Length s_support "Absolute position of support flange"; + equation + s = flange.s - s_support; + if not useSupport then + s_support = 0; + end if; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used to build up elementary components of a drive train with +equations in the text layer. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryOneFlangeAndSupport2; + + partial model PartialElementaryTwoFlangesAndSupport + "Obsolete partial model. Use PartialElementaryTwoFlangesAndSupport2." + extends Modelica.Icons.ObsoleteModel; + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left shaft" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right shaft" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.SIunits.Length s_a "Distance between left flange and support"; + Modelica.SIunits.Length s_b "Distance between right flange and support"; + protected + InternalSupport internalSupport(f=-flange_a.f - flange_b.f) + "Internal support/housing of component as a model with connector flange (flange is either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + public + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + equation + s_a = flange_a.s - internalSupport.s; + s_b = flange_b.s - internalSupport.s; + connect(internalSupport.flange, support) annotation (Line( + points={{0,-80},{0,-100}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, internalSupport.flange) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+This is a 1-dim. translational component with two flanges and an additional support. +It is used e.g., to build up elementary ideal gear components. The component +contains the force balance, i.e., the sum of the forces of the connectors +is zero (therefore, components that are based on PartialGear cannot have +a mass). The support connector needs to be connected +to avoid the unphysical behavior that the +support force is required to be zero (= the default value, if the +connector is not connected). +

+ +"), Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, + {100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryTwoFlangesAndSupport; + + partial model PartialElementaryTwoFlangesAndSupport2 + "Partial model for a component with one translational 1-dim. shaft flange and a support used for textual modeling, i.e., for elementary models" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left shaft" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right shaft" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support(s=s_support, f = -flange_a.f - flange_b.f) if useSupport + "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + Modelica.SIunits.Length s_a "Distance between left flange and support"; + Modelica.SIunits.Length s_b "Distance between right flange and support"; + protected + Modelica.SIunits.Length s_support "Absolute position of support flange"; + equation + s_a = flange_a.s - s_support; + s_b = flange_b.s - s_support; + if not useSupport then + s_support = 0; + end if; + + annotation (Documentation(info=" +

+This is a 1-dim. translational component with two flanges and an additional support. +It is used e.g., to build up elementary ideal gear components. The component +contains the force balance, i.e., the sum of the forces of the connectors +is zero (therefore, components that are based on PartialGear cannot have +a mass). The support connector needs to be connected +to avoid the unphysical behavior that the +support force is required to be zero (= the default value, if the +connector is not connected). +

+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryTwoFlangesAndSupport2; + + partial model PartialElementaryRotationalToTranslational + "Partial model to transform rotational into translational motion" + extends + Modelica.Mechanics.Rotational.Interfaces.PartialElementaryRotationalToTranslational; + annotation (Documentation(info=" +

This is a 1-dim. rotational component with

+
    +
  • one rotational flange,
  • +
  • one rotational support/housing,
  • +
  • one translational flange, and
  • +
  • one translational support/housing
  • +
+

This model is used to build up elementary components of a drive train transforming rotational into translational motion with equations in the text layer.

+

If useSupportR=true, the rotational support connector is conditionally enabled and needs to be connected.

+

If useSupportR=false, the rotational support connector is conditionally disabled and instead the rotational part is internally fixed to ground.

+

If useSupportT=true, the translational support connector is conditionally enabled and needs to be connected.

+

If useSupportT=false, the translational support connector is conditionally disabled and instead the translational part is internally fixed to ground.

+")); + end PartialElementaryRotationalToTranslational; + + partial model PartialForce + "Partial model of a force acting at the flange (accelerates the flange)" + extends PartialElementaryOneFlangeAndSupport2; + Modelica.SIunits.Force f "Accelerating force acting at flange (= flange.f)"; + equation + f = flange.f; + annotation ( + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100, + 100}}), graphics={ + Rectangle( + extent={{-96,96},{96,-96}}, + lineColor={255,255,255}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{0,-60},{0,-100}}, color={0,0,0}), + Text( + extent={{-150,140},{150,100}}, + lineColor={0,0,255}, + textString="%name"), + Line(points={{-78,80},{51,80}}, color={0,0,0}), + Polygon( + points={{81,80},{51,90},{51,70},{81,80}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-60},{77,-60}}, color={0,0,0}), + Polygon( + points={{-82,-60},{-51,-50},{-51,-70},{-82,-60}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})}), + Documentation(info=" +

+Partial model of force that accelerates the flange. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+")); + end PartialForce; + + partial model PartialAbsoluteSensor + "Device to measure a single absolute flange variable" + + extends Modelica.Icons.TranslationalSensor; + + Interfaces.Flange_a flange + "Flange to be measured (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + + equation + 0 = flange.f; + annotation ( + Documentation(info=" +

+This is the superclass of a 1D translational component with one flange and one +output signal in order to measure an absolute kinematic quantity in the flange +and to provide the measured signal as output signal for further processing +with the Modelica.Blocks blocks. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,-90},{-20,-90}}, color={0,0,0}), + Polygon( + points={{10,-90},{-20,-80},{-20,-100},{10,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{100,0}}, color={0,0,127}), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255})})); + end PartialAbsoluteSensor; + + partial model PartialRelativeSensor + "Device to measure a single relative variable between two flanges" + + extends Modelica.Icons.TranslationalSensor; + + Interfaces.Flange_a flange_a + "(left) driving flange (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Interfaces.Flange_b flange_b + "(right) driven flange (flange axis directed out of cut plane)" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + equation + 0 = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+This is a superclass for 1D translational components with two rigidly connected +flanges and one output signal in order to measure relative kinematic quantities +between the two flanges or the cut-force in the flange and +to provide the measured signal as output signal for further processing +with the Modelica.Blocks blocks. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-51,34},{29,34}}, color={0,0,0}), + Polygon( + points={{59,34},{29,44},{29,24},{59,34}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255})})); + end PartialRelativeSensor; + + partial model PartialFriction "Base model of Coulomb friction elements" + + //extends Translational.Interfaces.PartialRigid; + parameter SI.Velocity v_small=1e-3 + "Relative velocity near to zero (see model info text)" + annotation(Dialog(tab="Advanced")); + // Equations to define the following variables have to be defined in subclasses + SI.Velocity v_relfric "Relative velocity between frictional surfaces"; + SI.Acceleration a_relfric + "Relative acceleration between frictional surfaces"; + //SI.Force f "Friction force (positive, if directed in opposite direction of v_rel)"; + SI.Force f0 "Friction force for v=0 and forward sliding"; + SI.Force f0_max "Maximum friction force for v=0 and locked"; + Boolean free "true, if frictional element is not active"; + // Equations to define the following variables are given in this class + Real sa(unit="1") + "Path parameter of friction characteristic f = f(a_relfric)"; + Boolean startForward(start=false, fixed=true) + "true, if v_rel=0 and start of forward sliding"; + Boolean startBackward(start=false, fixed=true) + "true, if v_rel=0 and start of backward sliding"; + Boolean locked(start=false) "true, if v_rel=0 and not sliding"; + constant Integer Unknown=3 "Value of mode is not known"; + constant Integer Free=2 "Element is not active"; + constant Integer Forward=1 "v_rel > 0 (forward sliding)"; + constant Integer Stuck=0 + "v_rel = 0 (forward sliding, locked or backward sliding)"; + constant Integer Backward=-1 "v_rel < 0 (backward sliding)"; + Integer mode( + final min=Backward, + final max=Unknown, + start=Unknown, fixed=true); + protected + constant SI.Acceleration unitAcceleration = 1 annotation(HideResult=true); + constant SI.Force unitForce = 1 annotation(HideResult=true); + equation + /* Friction characteristic + (locked is introduced to help the Modelica translator determining + the different structural configurations, + if for each configuration special code shall be generated) +*/ + startForward = pre(mode) == Stuck and (sa > f0_max/unitForce or pre(startForward) + and sa > f0/unitForce) or pre(mode) == Backward and v_relfric > v_small or + initial() and (v_relfric > 0); + startBackward = pre(mode) == Stuck and (sa < -f0_max/unitForce or pre( + startBackward) and sa < -f0/unitForce) or pre(mode) == Forward and v_relfric < + -v_small or initial() and (v_relfric < 0); + locked = not free and not (pre(mode) == Forward or startForward or pre( + mode) == Backward or startBackward); + + a_relfric/unitAcceleration = if locked then 0 else + if free then sa else + if startForward then sa - f0_max/unitForce else + if startBackward then sa + f0_max/unitForce else + if pre(mode) == Forward then sa - f0_max/unitForce else + sa + f0_max/unitForce; + + /* Friction torque has to be defined in a subclass. Example for a clutch: + f = if locked then sa else + if free then 0 else + cgeo*fn*(if startForward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + if startBackward then -Math.tempInterpol1(-v_relfric, mue_pos, 2) else + if pre(mode) == Forward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + -Math.tempInterpol1(-v_relfric, mue_pos, 2)); +*/ + // finite state machine to determine configuration + mode = if free then Free else + (if (pre(mode) == Forward or pre(mode) == Free or startForward) and v_relfric > 0 then + Forward else + if (pre(mode) == Backward or pre(mode) == Free or startBackward) and v_relfric < 0 then + Backward else + Stuck); + annotation (Documentation(info=" +

+Basic model for Coulomb friction that models the stuck phase in a reliable way. +

+")); + end PartialFriction; + + annotation (Documentation(info=" +

+This package contains connectors and partial models for 1-dim. +translational mechanical components. The components of this package can +only be used as basic building elements for models. +

+ +")); + end Interfaces; + + annotation ( + Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100,-100},{100,100}}), graphics = { + Line( + origin = {14,53}, + points = {{-84,-73},{66,-73}}), + Rectangle( + origin = {14,53}, + lineColor = {64,64,64}, + fillColor = {192,192,192}, + fillPattern = FillPattern.Sphere, + extent = {{-81,-65},{-8,-22}}),Line(visible = true, + origin = {14,53}, + points = {{-8,-43},{-1,-43},{6,-64},{17,-23},{29,-65},{40,-23},{50,-44},{61,-44}}), + Line( + origin = {14,53}, + points = {{-59,-73},{-84,-93}}), + Line( + origin = {14,53}, + points = {{-11,-73},{-36,-93}}), + Line( + origin = {14,53}, + points = {{-34,-73},{-59,-93}}), + Line( + origin = {14,53}, + points = {{14,-73},{-11,-93}}), + Line( + origin = {14,53}, + points = {{39,-73},{14,-93}}), + Line( + origin = {14,53}, + points = {{63,-73},{38,-93}})}), + Documentation(info=" +

+This package contains components to model 1-dimensional translational +mechanical systems. +

+

+The filled and non-filled green squares at the left and +right side of a component represent mechanical flanges. +Drawing a line between such squares means that the corresponding +flanges are rigidly attached to each other. The components of this +library can be usually connected together in an arbitrary way. E.g. it is +possible to connect two springs or two sliding masses with inertia directly +together. +

The only connection restriction is that the Coulomb friction +elements (e.g., MassWithStopAndFriction) should be only connected +together provided a compliant element, such as a spring, is in between. +The reason is that otherwise the frictional force is not uniquely +defined if the elements are stuck at the same time instant (i.e., there +does not exist a unique solution) and some simulation systems may not be +able to handle this situation, since this leads to a singularity during +simulation. It can only be resolved in a \"clean way\" by combining the +two connected friction elements into +one component and resolving the ambiguity of the frictional force in the +stuck mode. +

+

Another restriction arises if the hard stops in model MassWithStopAndFriction are used, i. e. +the movement of the mass is limited by a stop at smax or smin. + This requires the states Stop.s and Stop.v . If these states are eliminated during the index reduction +the model will not work. To avoid this any inertias should be connected via springs +to the Stop element, other sliding masses, dampers or hydraulic chambers must be avoided.

+

+In the icon of every component an arrow is displayed in grey +color. This arrow characterizes the coordinate system in which the vectors +of the component are resolved. It is directed into the positive +translational direction (in the mathematical sense). +In the flanges of a component, a coordinate system is rigidly attached +to the flange. It is called flange frame and is directed in parallel +to the component coordinate system. As a result, e.g., the positive +cut-force of a \"left\" flange (flange_a) is directed into the flange, whereas +the positive cut-force of a \"right\" flange (flange_b) is directed out of the +flange. A flange is described by a Modelica connector containing +the following variables: +

+
+   Modelica.SIunits.Position s    \"Absolute position of flange\";
+   flow Modelica.SIunits.Force f  \"Cut-force in the flange\";
+
+ +

+This library is designed in a fully object oriented way in order that +components can be connected together in every meaningful combination +(e.g., direct connection of two springs or two shafts with inertia). +As a consequence, most models lead to a system of +differential-algebraic equations of index 3 (= constraint +equations have to be differentiated twice in order to arrive at +a state space representation) and the Modelica translator or +the simulator has to cope with this system representation. +According to our present knowledge, this requires that the +Modelica translator is able to symbolically differentiate equations +(otherwise it is e.g., not possible to provide consistent initial +conditions; even if consistent initial conditions are present, most +numerical DAE integrators can cope at most with index 2 DAEs). +

+ +

+In version 3.2 of the Modelica Standard Library, all dissipative components +of the Translational library got an optional heatPort connector to which the +dissipated energy is transported in form of heat. This connector is enabled +via parameter \"useHeatPort\". If the heatPort connector is enabled, +it must be connected, and if it is not enabled, it must not be connected. +Independently, whether the heatPort is enabled or not, +the dissipated power is available from the new variable \"lossPower\" (which is +positive if heat is flowing out of the heatPort). For an example, see +Examples.HeatLosses. +

+ +
+
Library Officer +
Martin Otter
+ Deutsches Zentrum für Luft und Raumfahrt e.V. (DLR)
+ Institut für Robotik und Mechatronik (DLR-RM)
+ Abteilung Systemdynamik und Regelungstechnik
+ Postfach 1116
+ D-82230 Wessling
+ Germany
+ email: Martin.Otter@dlr.de

+
+ +

+Contributors to this library: +

+ +
    +
  • Main author until 2006:
    + Peter Beater
    + Universität Paderborn, Abteilung Soest
    + Fachbereich Maschinenbau/Automatisierungstechnik
    + Lübecker Ring 2
    + D 59494 Soest
    + Germany
    + email: info@beater.de

    +
  • + +
  • Anton Haumer
    + Technical Consulting & Electrical Engineering
    + A-3423 St.Andrae-Woerdern, Austria
    + email: a.haumer@haumer.at

  • + +
  • Martin Otter (DLR-RM)
  • +
+ +

+Copyright © 1998-2013, Modelica Association, Anton Haumer and Universität Paderborn, FB 12. +

+

+This Modelica package is free software and the use is completely at your own risk; it can be redistributed and/or modified under the terms of the Modelica License 2. For license conditions (including the disclaimer of warranty) see Modelica.UsersGuide.ModelicaLicense2 or visit https://www.modelica.org/licenses/ModelicaLicense2. +

+", revisions=" +
    +
  • Version 1.2.0 2010-07-22 + by Anton Haumer and Martin Otter
    + heatPort introduced for all dissipative elements, and + text in icons improved. +
  • + +
  • Version 1.1.0 2007-11-16 + by Anton Haumer
    + Redesign for Modelica 3.0-compliance
    + Added new components according to Mechanics.Rotational library +
  • + +
  • Version 1.01 (July 18, 2001) + by Peter Beater
    + Assert statement added to \"Stop\", small bug fixes in examples. +
  • + +
  • Version 1.0 (January 5, 2000) + by Peter Beater
    + Realized a first version based on Modelica library Mechanics.Rotational + by Martin Otter and an existing Dymola library onedof.lib by Peter Beater.
  • +
+")); +end Translational; diff --git a/samples/Modelica/modelica.mo b/samples/Modelica/modelica.mo new file mode 100644 index 00000000..5462de87 --- /dev/null +++ b/samples/Modelica/modelica.mo @@ -0,0 +1,285 @@ +within Modelica.Electrical.Analog; +package Sensors "Potential, voltage, current, and power sensors" + + extends Modelica.Icons.SensorsPackage; + + model PotentialSensor "Sensor to measure the potential" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "pin to be measured" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput phi + "Absolute voltage potential as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + equation + p.i = 0; + phi = p.v; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="V"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{100,0},{70,0}}, color={0,0,255}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{100,0},{70,0}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The potential sensor converts the voltage of a node (with respect to the ground node) into a real valued signal. It does not influence the current sum at the node which voltage is measured, therefore, the electrical behavior is not influenced by the sensor.

+")); + end PotentialSensor; + + model VoltageSensor "Sensor to measure the voltage between two pins" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "positive pin" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Interfaces.NegativePin n "negative pin" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput v + "Voltage between pin p and n (= p.v - n.v) as output signal" + annotation (Placement(transformation( + origin={0,-100}, + extent={{10,-10},{-10,10}}, + rotation=90))); + + equation + p.i = 0; + n.i = 0; + v = p.v - n.v; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="V"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{70,0},{96,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The voltage sensor converts the voltage between the two connectors into a real valued signal. It does not influence the current sum at the nodes in between the voltage is measured, therefore, the electrical behavior is not influenced by the sensor.

+")); + end VoltageSensor; + + model CurrentSensor "Sensor to measure the current in a branch" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "positive pin" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Interfaces.NegativePin n "negative pin" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput i + "current in the branch from p to n as output signal" + annotation (Placement(transformation( + origin={0,-100}, + extent={{10,-10},{-10,10}}, + rotation=90))); + + equation + p.v = n.v; + p.i = i; + n.i = -i; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="A"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-153,79},{147,119}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{70,0},{96,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The current sensor converts the current flowing between the two connectors into a real valued signal. The two connectors are in the sensor connected like a short cut. The sensor has to be placed within an electrical connection in series. It does not influence the current sum at the connected nodes. Therefore, the electrical behavior is not influenced by the sensor.

+")); + end CurrentSensor; + +model PowerSensor "Sensor to measure the power" + + Modelica.Electrical.Analog.Interfaces.PositivePin pc + "Positive pin, current path" + annotation (Placement(transformation(extent={{-90,-10},{-110,10}}, rotation= + 0))); + Modelica.Electrical.Analog.Interfaces.NegativePin nc + "Negative pin, current path" + annotation (Placement(transformation(extent={{110,-10},{90,10}}, rotation=0))); + Modelica.Electrical.Analog.Interfaces.PositivePin pv + "Positive pin, voltage path" + annotation (Placement(transformation(extent={{-10,110},{10,90}}, rotation=0))); + Modelica.Electrical.Analog.Interfaces.NegativePin nv + "Negative pin, voltage path" + annotation (Placement(transformation(extent={{10,-110},{-10,-90}}, rotation= + 0))); + Modelica.Blocks.Interfaces.RealOutput power + annotation (Placement(transformation( + origin={-80,-110}, + extent={{-10,10},{10,-10}}, + rotation=270))); + Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor + annotation (Placement(transformation( + origin={0,-30}, + extent={{10,-10},{-10,10}}, + rotation=90))); + Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor + annotation (Placement(transformation(extent={{-50,-10},{-30,10}}, rotation= + 0))); + Modelica.Blocks.Math.Product product + annotation (Placement(transformation( + origin={-30,-50}, + extent={{-10,-10},{10,10}}, + rotation=270))); + +equation + connect(pv, voltageSensor.p) annotation (Line(points={{0,100},{0,-20},{ + 6.12323e-016,-20}}, color={0,0,255})); + connect(voltageSensor.n, nv) annotation (Line(points={{-6.12323e-016,-40},{ + -6.12323e-016,-63},{0,-63},{0,-100}}, color={0,0,255})); + connect(pc, currentSensor.p) + annotation (Line(points={{-100,0},{-50,0}}, color={0,0,255})); + connect(currentSensor.n, nc) + annotation (Line(points={{-30,0},{100,0}}, color={0,0,255})); + connect(currentSensor.i, product.u2) annotation (Line(points={{-40,-10},{-40, + -30},{-36,-30},{-36,-38}}, color={0,0,127})); + connect(voltageSensor.v, product.u1) annotation (Line(points={{10,-30},{-24, + -30},{-24,-38}}, color={0,0,127})); + connect(product.y, power) annotation (Line(points={{-30,-61},{-30,-80},{-80, + -80},{-80,-110}}, color={0,0,127})); + annotation (Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={2,2}), graphics={ + Ellipse( + extent={{-70,70},{70,-70}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{0,100},{0,70}}, color={0,0,255}), + Line(points={{0,-70},{0,-100}}, color={0,0,255}), + Line(points={{-80,-100},{-80,0}}, color={0,0,255}), + Line(points={{-100,0},{100,0}}, color={0,0,255}), + Text( + extent={{150,120},{-150,160}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{0,70},{0,40}}, color={0,0,0}), + Line(points={{22.9,32.8},{40.2,57.3}}, color={0,0,0}), + Line(points={{-22.9,32.8},{-40.2,57.3}}, color={0,0,0}), + Line(points={{37.6,13.7},{65.8,23.9}}, color={0,0,0}), + Line(points={{-37.6,13.7},{-65.8,23.9}}, color={0,0,0}), + Line(points={{0,0},{9.02,28.6}}, color={0,0,0}), + Polygon( + points={{-0.48,31.6},{18,26},{18,57.2},{-0.48,31.6}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-5,5},{5,-5}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="P")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={2,2}), graphics), + Documentation(info=" +

This power sensor measures instantaneous electrical power of a singlephase system and has a separated voltage and current path. The pins of the voltage path are pv and nv, the pins of the current path are pc and nc. The internal resistance of the current path is zero, the internal resistance of the voltage path is infinite.

+", revisions=" +
    +
  • January 12, 2006 by Anton Haumer implemented
  • +
+")); +end PowerSensor; + annotation ( + Documentation(info=" +

This package contains potential, voltage, and current sensors. The sensors can be used to convert voltages or currents into real signal values o be connected to components of the Blocks package. The sensors are designed in such a way that they do not influence the electrical behavior.

+", + revisions=" +
+
+Main Authors: +
+Christoph Clauß + <Christoph.Clauss@eas.iis.fraunhofer.de>
+ André Schneider + <Andre.Schneider@eas.iis.fraunhofer.de>
+ Fraunhofer Institute for Integrated Circuits
+ Design Automation Department
+ Zeunerstraße 38
+ D-01069 Dresden
+

+

+Copyright: +
+Copyright © 1998-2010, Modelica Association and Fraunhofer-Gesellschaft.
+The Modelica package is free software; it can be redistributed and/or modified +under the terms of the Modelica license, see the license conditions +and the accompanying disclaimer in the documentation of package +Modelica in file \"Modelica/package.mo\".
+

+

+")); +end Sensors; diff --git a/samples/NewLisp/irc.lsp b/samples/NewLisp/irc.lsp new file mode 100644 index 00000000..0cac4034 --- /dev/null +++ b/samples/NewLisp/irc.lsp @@ -0,0 +1,239 @@ +#!/usr/bin/env newlisp + +;; @module IRC +;; @description a basic irc library +;; @version early alpha! 0.1 2013-01-02 20:11:22 +;; @author cormullion +;; Usage: +;; (IRC:init "newlithper") ; a username/nick (not that one obviously :-) +;; (IRC:connect "irc.freenode.net" 6667) ; irc/server +;; (IRC:join-channel {#newlisp}) ; join a room +;; either (IRC:read-irc-loop) ; loop - monitor only, no input +;; or (IRC:session) ; a command-line session, end with /QUIT + +(context 'IRC) + (define Inickname) + (define Ichannels) + (define Iserver) + (define Iconnected) + (define Icallbacks '()) + (define Idle-time 400) ; seconds + (define Itime-stamp) ; time since last message was processed + +(define (register-callback callback-name callback-function) + (println {registering callback for } callback-name { : } (sym (term callback-function) (prefix callback-function))) + (push (list callback-name (sym (term callback-function) (prefix callback-function))) Icallbacks)) + +(define (deregister-callback callback-name) + (println {deregistering callback for } callback-name) + (setf (assoc "idle-event" Icallbacks) nil) + (println {current callbacks: } Icallbacks)) + +(define (do-callback callback-name data) + (when (set 'func (lookup callback-name Icallbacks)) ; find first callback + (if-not (catch (apply func (list data)) 'error) + (println {error in callback } callback-name {: } error)))) + +(define (do-callbacks callback-name data) + (dolist (rf (ref-all callback-name Icallbacks)) + (set 'callback-entry (Icallbacks (first rf))) + (when (set 'func (last callback-entry)) + (if-not (catch (apply func (list data)) 'error) + (println {error in callback } callback-name {: } error))))) + +(define (init str) + (set 'Inickname str) + (set 'Iconnected nil) + (set 'Ichannels '()) + (set 'Itime-stamp (time-of-day))) + +(define (connect server port) + (set 'Iserver (net-connect server port)) + (net-send Iserver (format "USER %s %s %s :%s\r\n" Inickname Inickname Inickname Inickname)) + (net-send Iserver (format "NICK %s \r\n" Inickname)) + (set 'Iconnected true) + (do-callbacks "connect" (list (list "server" server) (list "port" port)))) + +(define (identify password) + (net-send Iserver (format "PRIVMSG nickserv :identify %s\r\n" password))) + +(define (join-channel channel) + (when (net-send Iserver (format "JOIN %s \r\n" channel)) + (push channel Ichannels) + (do-callbacks "join-channel" (list (list "channel" channel) (list "nickname" Inickname))))) + +(define (part chan) + (if-not (empty? chan) + ; leave specified + (begin + (net-send Iserver (format "PART %s\r\n" chan)) + (replace channel Ichannels) + (do-callbacks "part" (list (list "channel" channel)))) + ; leave all + (begin + (dolist (channel Ichannels) + (net-send Iserver (format "PART %s\r\n" channel)) + (replace channel Ichannels) + (do-callbacks "part" (list (list "channel" channel))))))) + +(define (do-quit message) + (do-callbacks "quit" '()) ; chance to do stuff before quit... + (net-send Iserver (format "QUIT :%s\r\n" message)) + (sleep 1000) + (set 'Ichannels '()) + (close Iserver) + (set 'Iconnected nil)) + +(define (privmsg user message) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" user message))) + +(define (notice user message) + (net-send Iserver (format "NOTICE %s :%s\r\n" user message))) + +(define (send-to-server message (channel nil)) + (cond + ((starts-with message {/}) ; default command character + (set 'the-message (replace "^/" (copy message) {} 0)) ; keep original + (net-send Iserver (format "%s \r\n" the-message)) ; send it + ; do a quit + (if (starts-with (lower-case the-message) "quit") + (do-quit { enough}))) + (true + (if (nil? channel) + ; say to all channels + (dolist (c Ichannels) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" c message))) + ; say to specified channel + (if (find channel Ichannels) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" channel message)))))) + (do-callbacks "send-to-server" (list (list "channel" channel) (list "message" message)))) + +(define (process-command sender command text) + (cond + ((= sender "PING") + (net-send Iserver (format "PONG %s\r\n" command))) + ((or (= command "NOTICE") (= command "PRIVMSG")) + (process-message sender command text)) + ((= command "JOIN") + (set 'username (first (clean empty? (parse sender {!|:} 0)))) + (set 'channel (last (clean empty? (parse sender {!|:} 0)))) + (println {username } username { joined } channel) + (do-callbacks "join" (list (list "channel" channel) (list "username" username)))) + (true + nil))) + +(define (process-message sender command text) + (let ((username {} target {} message {})) + (set 'username (first (clean empty? (parse sender {!|:} 0)))) + (set 'target (trim (first (clean empty? (parse text {!|:} 0))))) + (set 'message (slice text (+ (find {:} text) 1))) + (cond + ((starts-with message "\001") + (process-ctcp username target message)) + ((find target Ichannels) + (cond + ((= command {PRIVMSG}) + (do-callbacks "channel-message" (list (list "channel" target) (list "username" username) (list "message" message)))) + ((= command {NOTICE}) + (do-callbacks "channel-notice" (list (list "channel" target) (list "username" username) (list "message" message)))))) + ((= target Inickname) + (cond + ((= command {PRIVMSG}) + (do-callbacks "private-message" (list (list "username" username) (list "message" message)))) + ((= command {NOTICE}) + (do-callbacks "private-notice" (list (list "username" username) (list "message" message)))))) + (true + nil)))) + +(define (process-ctcp username target message) + (cond + ((starts-with message "\001VERSION\001") + (net-send Iserver (format "NOTICE %s :\001VERSION %s\001\r\n" username message))) + ((starts-with message "\001PING") + (set 'data (first (rest (clean empty? (parse message { } 0))))) + (set 'data (trim data "\001" "\001")) + (net-send Iserver (format "NOTICE %s :\001PING %s\001\r\n" username data))) + ((starts-with message "\001ACTION") +; (set 'data (first (rest (clean empty? (parse message { } 0))))) +; (set 'data (join data { })) +; (set 'data (trim data "\001" "\001")) + (if (find target Ichannels) + (do-callbacks "channel-action" (list (list "username" username) (list "message" message)))) + (if (= target Inickname) + (do-callbacks "private-action" (list (list "username" username) (list "message" message))))) + ((starts-with message "\001TIME\001") + (net-send Iserver (format "NOTICE %s:\001TIME :%s\001\r\n" username (date)))))) + +(define (parse-buffer raw-buffer) + (let ((messages (clean empty? (parse raw-buffer "\r\n" 0))) + (sender {} command {} text {})) + ; check for elapsed time since last activity + (when (> (sub (time-of-day) Itime-stamp) (mul Idle-time 1000)) + (do-callbacks "idle-event") + (set 'Itime-stamp (time-of-day))) + (dolist (message messages) + (set 'message-parts (parse message { })) + (unless (empty? message-parts) + (set 'sender (first message-parts)) + (catch (set 'command (first (rest message-parts))) 'error) + (catch (set 'text (join (rest (rest message-parts)) { })) 'error)) + (process-command sender command text)))) + +(define (read-irc) + (let ((buffer {})) + (when (!= (net-peek Iserver) 0) + (net-receive Iserver buffer 8192 "\n") + (unless (empty? buffer) + (parse-buffer buffer))))) + +(define (read-irc-loop) ; monitoring + (let ((buffer {})) + (while Iconnected + (read-irc) + (sleep 1000)))) + +(define (print-raw-message data) ; example of using a callback + (set 'raw-data (lookup "message" data)) + (set 'channel (lookup "channel" data)) + (set 'message-text raw-data) + (println (date (date-value) 0 {%H:%M:%S }) username {> } message-text)) + +(define (print-outgoing-message data) + (set 'raw-data (lookup "message" data)) + (set 'channel (lookup "channel" data)) + (set 'message-text raw-data) + (println (date (date-value) 0 {%H:%M:%S }) Inickname {> } message-text)) + +(define (session); interactive terminal + ; must add callbacks to display messages + (register-callback "channel-message" 'print-raw-message) + (register-callback "send-to-server" 'print-outgoing-message) + (while Iconnected + (while (zero? (peek 0)) + (read-irc) + (sleep 1000)) + (send-to-server (string (read-line 0)))) + (println {finished session } (date)) + (exit)) + +; end of IRC code + +[text] + +simple bot code: +(load (string (env {HOME}) {/projects/programming/newlisp-projects/irc.lsp})) +(context 'BOT) +(define bot-name "bot") +(define (join-channel data) + (println {in BOT:join-channel with data: } data)) +(define (process-message data) + ????) +(IRC:register-callback "join-channel" 'join-channel) +(IRC:register-callback "channel-message" 'process-message) +(IRC:register-callback "idle-event" 'do-idle-event) +(IRC:register-callback "send-to-server" 'do-send-event) +(IRC:init bot-name) +(IRC:connect "irc.freenode.net" 6667) +(IRC:join-channel {#newlisp}) +(IRC:read-irc-loop) +[/text] \ No newline at end of file diff --git a/samples/NewLisp/log-to-database.lisp b/samples/NewLisp/log-to-database.lisp new file mode 100644 index 00000000..60af8406 --- /dev/null +++ b/samples/NewLisp/log-to-database.lisp @@ -0,0 +1,195 @@ +(module "sqlite3.lsp") ; loads the SQLite3 database module + +; FUNCTIONS------------------------------------------------- + +(define (displayln str-to-display) + (println str-to-display) +) + +(define (open-database sql-db-to-open) + (if (sql3:open (string sql-db-to-open ".db")) + (displayln "") + (displayln "There was a problem opening the database " sql-db-to-open ": " (sql3:error)))) + +(define (close-database) + (if (sql3:close) + (displayln "") + (displayln "There was a problem closing the database: " (sql3:error)))) + +;====== SAFE-FOR-SQL =============================================================== +; this function makes strings safe for inserting into SQL statements +; to avoid SQL injection issues +; it's simple right now but will add to it later +;=================================================================================== +(define (safe-for-sql str-sql-query) + (if (string? str-sql-query) (begin + (replace "&" str-sql-query "&") + (replace "'" str-sql-query "'") + (replace "\"" str-sql-query """) + )) + (set 'result str-sql-query)) + +(define (query sql-text) + (set 'sqlarray (sql3:sql sql-text)) ; results of query + (if sqlarray + (setq query-return sqlarray) + (if (sql3:error) + (displayln (sql3:error) " query problem ") + (setq query-return nil)))) + +(define-macro (create-record) + ; first save the values + (set 'temp-record-values nil) + (set 'temp-table-name (first (args))) + ;(displayln "
Arguments: " (args)) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) + ; now save the arguments as symbols under the context "DB" + (dolist (s (rest (args))) + (set 'temp-index-num (string $idx)) ; we need to number the symbols to keep them in the correct order + (if (= (length temp-index-num) 1) (set 'temp-index-num (string "0" temp-index-num))) ; leading 0 keeps the max at 100. + (sym (string temp-index-num s) 'DB)) + ; now create the sql query + (set 'temp-sql-query (string "INSERT INTO " temp-table-name " (")) + ;(displayln "

TABLE NAME: " temp-table-name) + ;(displayln "

SYMBOLS: " (symbols DB)) + ;(displayln "
VALUES: " temp-record-values) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (rest (rest (string d)))))) ", ")) + (set 'temp-sql-query (chop (chop temp-sql-query))) + (extend temp-sql-query ") VALUES (") + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'")) ; close quote if value is non-numeric + (extend temp-sql-query ", ")) ; all values are sanitized to avoid SQL injection + (set 'temp-sql-query (chop (chop temp-sql-query))) + (extend temp-sql-query ");") + ;(displayln "

***** SQL QUERY: " temp-sql-query) + (displayln (query temp-sql-query)) ; actually run the query against the database + (delete 'DB) ; we're done, so delete all symbols in the DB context. +) + +(define-macro (update-record) + ; first save the values + (set 'temp-record-values nil) + (set 'temp-table-name (first (args))) + (set 'continue true) ; debugging + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) + ; now save the arguments as symbols under the context "D2" + (dolist (st (rest (args))) + (set 'temp-index-num (string $idx)) ; we need to number the symbols to keep them in the correct order + (if (= (length temp-index-num) 1) (set 'temp-index-num (string "0" temp-index-num))) ; leading 0 keeps the max at 100. + ;(displayln "
SYMBOL>>>>" (string temp-index-num st) "<<<") ; debugging + (sym (string temp-index-num st) 'D2) + ) + (if continue (begin ; --- temporary debugging + ; now create the sql query + (set 'temp-sql-query (string "UPDATE " temp-table-name " SET ")) + ;(displayln "

TABLE NAME: " temp-table-name) + ;(displayln "

SYMBOLS: " (symbols D2)) + ;(displayln "
VALUES: " temp-record-values) + (dolist (d (rest (symbols D2))) ; ignore the first argument, as it will be the ConditionColumn for later + (extend temp-sql-query (rest (rest (rest (rest (rest (string d)))))) "=") + (set 'q (temp-record-values (+ $idx 1))) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'")) ; close quote if value is non-numeric + (extend temp-sql-query ", ") ; all values are sanitized to avoid SQL injection + ) + (set 'temp-sql-query (chop (chop temp-sql-query))) + ; okay now add the ConditionColumn value + (extend temp-sql-query (string " WHERE " (rest (rest (rest (rest (rest (string (first (symbols D2)))))))) "=")) + (if (string? (first temp-record-values)) (extend temp-sql-query "'")) + (extend temp-sql-query (string (safe-for-sql (first temp-record-values)))) + (if (string? (first temp-record-values)) (extend temp-sql-query "'")) + (extend temp-sql-query ";") + ;(displayln "

***** SQL QUERY: " temp-sql-query) + (query temp-sql-query) ; actually run the query against the database + (delete 'D2) ; we're done, so delete all symbols in the DB context. + )) ; --- end temporary debugging +) + +(define-macro (delete-record) + (set 'temp-table-name (first (args))) + (set 'temp-record-values nil) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) ; only one value for NOW... + (sym (first (rest (args))) 'DB) ; put the second argument (for now) into a symbol in the DB context + ; this will have to be in a dolist loop of (rest (args)) when I add more + (set 'temp-sql-query (string "DELETE FROM " temp-table-name " WHERE ")) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (string d)))))) + (extend temp-sql-query "=") + ; why am I doing a loop here? There should be only one value, right? But maybe for future extension... + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'"))) ; close quote if value is non-numeric + (extend temp-sql-query ";") + ;(displayln "TEMP-DELETE-QUERY: " temp-sql-query) + (query temp-sql-query) + (delete 'DB) ; we're done, so delete all symbols in the DB context. +) + +(define-macro (get-record) + (set 'temp-table-name (first (args))) + ; if you have more arguments than just the table name, they become the elements of the WHERE clause + (if (> (length (args)) 1) (begin + (set 'temp-record-values nil) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) ; only one value for NOW... + (sym (first (rest (args))) 'DB) ; put the second argument (for now) into a symbol in the DB context + ; this will have to be in a dolist loop of (rest (args)) when I add more + (set 'temp-sql-query (string "SELECT * FROM " temp-table-name " WHERE ")) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (string d)))))) + (extend temp-sql-query "=") + ; why am I doing a loop here? There should be only one value, right? But maybe for future extension... + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'"))) ; close quote if value is non-numeric + (extend temp-sql-query ";") + ) + ; otherwise, just get everything in that table + (set 'temp-sql-query (string "SELECT * FROM " temp-table-name ";")) + ) + ;(displayln "TEMP-GET-QUERY: " temp-sql-query) + (delete 'DB) ; we're done, so delete all symbols in the DB context. + (set 'return-value (query temp-sql-query)) ; this returns a list of everything in the record +) + +; END FUNCTIONS =================== + + +(open-database "SERVER-LOGS") +(query "CREATE TABLE Logs (Id INTEGER PRIMARY KEY, IP TEXT, UserId TEXT, UserName TEXT, Date DATE, Request TEXT, Result TEXT, Size INTEGER, Referrer TEXT, UserAgent TEXT)") +;(print (query "SELECT * from SQLITE_MASTER;")) +(set 'access-log (read-file "/var/log/apache2/access.log")) +(set 'access-list (parse access-log "\n")) +(set 'max-items (integer (first (first (query "select count(*) from Logs"))))) +(println "Number of items in database: " max-items) +(println "Number of lines in log: " (length access-list)) +(dolist (line access-list) + (set 'line-list (parse line)) + ;(println "Line# " $idx " - " line-list) + ;(println "Length of line: " (length line-list)) + (if (> (length line-list) 0) (begin + (++ max-items) + (set 'Id max-items) (print $idx "/" (length access-list)) + (set 'IP (string (line-list 0) (line-list 1) (line-list 2))) + (set 'UserId (line-list 3)) + (set 'UserName (line-list 4)) + (set 'Date (line-list 5)) + (set 'Date (trim Date "[")) + (set 'Date (trim Date "]")) + ;(println "DATE: " Date) + (set 'date-parsed (date-parse Date "%d/%b/%Y:%H:%M:%S -0700")) + ;(println "DATE-PARSED: " date-parsed) + (set 'Date (date date-parsed 0 "%Y-%m-%dT%H:%M:%S")) + (println " " Date) + (set 'Request (line-list 6)) + (set 'Result (line-list 7)) + (set 'Size (line-list 8)) + (set 'Referrer (line-list 9)) + (set 'UserAgent (line-list 10)) + (create-record "Logs" Id IP UserId UserName Date Request Result Size Referrer UserAgent) + )) +) +(close-database) +(exit) \ No newline at end of file diff --git a/samples/Pascal/cwindirs.pp b/samples/Pascal/cwindirs.pp new file mode 100644 index 00000000..d97895e3 --- /dev/null +++ b/samples/Pascal/cwindirs.pp @@ -0,0 +1,121 @@ + +unit cwindirs; + + + + +interface + +uses + windows, + strings; + +Const + CSIDL_PROGRAMS = $0002; + CSIDL_PERSONAL = $0005; + CSIDL_FAVORITES = $0006; + CSIDL_STARTUP = $0007; + CSIDL_RECENT = $0008; + CSIDL_SENDTO = $0009; + CSIDL_STARTMENU = $000B; + CSIDL_MYMUSIC = $000D; + CSIDL_MYVIDEO = $000E; + CSIDL_DESKTOPDIRECTORY = $0010; + CSIDL_NETHOOD = $0013; + CSIDL_TEMPLATES = $0015; + CSIDL_COMMON_STARTMENU = $0016; + CSIDL_COMMON_PROGRAMS = $0017; + CSIDL_COMMON_STARTUP = $0018; + CSIDL_COMMON_DESKTOPDIRECTORY = $0019; + CSIDL_APPDATA = $001A; + CSIDL_PRINTHOOD = $001B; + CSIDL_LOCAL_APPDATA = $001C; + CSIDL_COMMON_FAVORITES = $001F; + CSIDL_INTERNET_CACHE = $0020; + CSIDL_COOKIES = $0021; + CSIDL_HISTORY = $0022; + CSIDL_COMMON_APPDATA = $0023; + CSIDL_WINDOWS = $0024; + CSIDL_SYSTEM = $0025; + CSIDL_PROGRAM_FILES = $0026; + CSIDL_MYPICTURES = $0027; + CSIDL_PROFILE = $0028; + CSIDL_PROGRAM_FILES_COMMON = $002B; + CSIDL_COMMON_TEMPLATES = $002D; + CSIDL_COMMON_DOCUMENTS = $002E; + CSIDL_COMMON_ADMINTOOLS = $002F; + CSIDL_ADMINTOOLS = $0030; + CSIDL_COMMON_MUSIC = $0035; + CSIDL_COMMON_PICTURES = $0036; + CSIDL_COMMON_VIDEO = $0037; + CSIDL_CDBURN_AREA = $003B; + CSIDL_PROFILES = $003E; + + CSIDL_FLAG_CREATE = $8000; + +Function GetWindowsSpecialDir(ID : Integer) : String; + +implementation + +uses + sysutils; + +Type + PFNSHGetFolderPath = Function(Ahwnd: HWND; Csidl: Integer; Token: THandle; Flags: DWord; Path: PChar): HRESULT; stdcall; + + +var + SHGetFolderPath : PFNSHGetFolderPath = Nil; + CFGDLLHandle : THandle = 0; + +Procedure InitDLL; + +Var + pathBuf: array[0..MAX_PATH-1] of char; + pathLength: Integer; +begin + { Load shfolder.dll using a full path, in order to prevent spoofing (Mantis #18185) + Don't bother loading shell32.dll because shfolder.dll itself redirects SHGetFolderPath + to shell32.dll whenever possible. } + pathLength:=GetSystemDirectory(pathBuf, MAX_PATH); + if (pathLength>0) and (pathLength0) then + begin + Pointer(ShGetFolderPath):=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA'); + If @ShGetFolderPath=nil then + begin + FreeLibrary(CFGDLLHandle); + CFGDllHandle:=0; + end; + end; + end; + If (@ShGetFolderPath=Nil) then + Raise Exception.Create('Could not determine SHGetFolderPath Function'); +end; + +Function GetWindowsSpecialDir(ID : Integer) : String; + +Var + APath : Array[0..MAX_PATH] of char; + +begin + Result:=''; + if (CFGDLLHandle=0) then + InitDLL; + If (SHGetFolderPath<>Nil) then + begin + if SHGetFolderPath(0,ID or CSIDL_FLAG_CREATE,0,0,@APATH[0])=S_OK then + Result:=IncludeTrailingPathDelimiter(StrPas(@APath[0])); + end; +end; + +Initialization +Finalization + if CFGDLLHandle<>0 then + FreeLibrary(CFGDllHandle); +end. + diff --git a/samples/Pascal/gtkextra.pp b/samples/Pascal/gtkextra.pp deleted file mode 100644 index 9f2ebf8c..00000000 --- a/samples/Pascal/gtkextra.pp +++ /dev/null @@ -1,51 +0,0 @@ -{ $Id$ } -{ - --------------------------------------------------------------------------- - gtkextra.pp - GTK(2) widgetset - additional gdk/gtk functions - --------------------------------------------------------------------------- - - This unit contains missing gdk/gtk functions and defines for certain - versions of gtk or fpc. - - --------------------------------------------------------------------------- - - @created(Sun Jan 28th WET 2006) - @lastmod($Date$) - @author(Marc Weustink ) - - ***************************************************************************** - This file is part of the Lazarus Component Library (LCL) - - See the file COPYING.modifiedLGPL.txt, included in this distribution, - for details about the license. - ***************************************************************************** - } - -unit GtkExtra; - -{$mode objfpc}{$H+} - -interface - -{$I gtkdefines.inc} - -{$ifdef gtk1} -{$I gtk1extrah.inc} -{$endif} - -{$ifdef gtk2} -{$I gtk2extrah.inc} -{$endif} - - -implementation - -{$ifdef gtk1} -{$I gtk1extra.inc} -{$endif} - -{$ifdef gtk2} -{$I gtk2extra.inc} -{$endif} - -end. diff --git a/samples/Pascal/large.pp b/samples/Pascal/large.pp new file mode 100644 index 00000000..9e0f4867 --- /dev/null +++ b/samples/Pascal/large.pp @@ -0,0 +1,22 @@ +program large; + + const + max = 100000000; + + type + tlist = array[1..max] of longint; + + var + data : tlist; + i : integer; + +begin + + i := 0; + while(i < max) + do + begin + data[i] := 0; + Writeln(data[i]) + end +end. diff --git a/samples/Pascal/tw27294.pp b/samples/Pascal/tw27294.pp new file mode 100644 index 00000000..34d14f5d --- /dev/null +++ b/samples/Pascal/tw27294.pp @@ -0,0 +1,26 @@ +uses + uw27294; + +var + p : procedure; + +procedure test; + +begin + p:=@test; + writeln('OK'); +end; + +procedure global; +begin + p:=nil; + test; + p(); +end; + +begin + global; + uw27294.global; +end. + + diff --git a/samples/PowerShell/ZLocation.psd1 b/samples/PowerShell/ZLocation.psd1 new file mode 100644 index 00000000..fcf90ef9 --- /dev/null +++ b/samples/PowerShell/ZLocation.psd1 @@ -0,0 +1,116 @@ +# +# Module manifest for module 'ZLocation' +# +# Generated by: sevoroby +# +# Generated on: 12/10/2014 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'ZLocation.psm1' + +# Version number of this module. +ModuleVersion = '0.1' + +# ID used to uniquely identify this module +GUID = '18e8ca17-7f67-4f1c-85ff-159373bf66f5' + +# Author of this module +Author = 'Sergei Vorobev' + +# Company or vendor of this module +CompanyName = 'Microsoft' + +# Copyright statement for this module +Copyright = '(c) 2014 Sergei Vorobev. All rights reserved.' + +# Description of the functionality provided by this module +# Description = '' + +# Minimum version of the Windows PowerShell engine required by this module +# PowerShellVersion = '' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +NestedModules = @("ZLocation.Storage.psm1", "ZLocation.Search.psm1") + +# Functions to export from this module +FunctionsToExport = '*' + +# Cmdlets to export from this module +CmdletsToExport = '*' + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases to export from this module +AliasesToExport = '*' + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} diff --git a/samples/PowerShell/ZLocation.psm1 b/samples/PowerShell/ZLocation.psm1 new file mode 100644 index 00000000..5ab91146 --- /dev/null +++ b/samples/PowerShell/ZLocation.psm1 @@ -0,0 +1,91 @@ +# +# Weight function. +# +function Update-ZLocation([string]$path) +{ + $now = [datetime]::Now + if (Test-Path variable:global:__zlocation_current) + { + $prev = $global:__zlocation_current + $weight = $now.Subtract($prev.Time).TotalSeconds + Add-ZWeight ($prev.Location) $weight + } + + $global:__zlocation_current = @{ + Location = $path + Time = [datetime]::Now + } + + # populate folder immidiatly after the first cd + Add-ZWeight $path 0 +} + +# this approach hurts `cd` performance (0.0008 sec vs 0.025 sec). +# Consider replace it with OnIdle Event. +(Get-Variable pwd).attributes.Add((new-object ValidateScript { Update-ZLocation $_.Path; return $true })) +# +# End of weight function. +# + + +# +# Tab complention. +# +if (Test-Path Function:\TabExpansion) { + Rename-Item Function:\TabExpansion PreZTabExpansion +} + +function Get-EscapedPath +{ + param( + [Parameter( + Position=0, + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true) + ] + [string]$path + ) + + process { + if ($path.Contains(' ')) + { + return '"' + $path + '"' + } + return $path + } +} + +function global:TabExpansion($line, $lastWord) { + switch -regex ($line) { + "^(Set-ZLocation|z) .*" { + $arguments = $line -split ' ' | Where { $_.length -gt 0 } | select -Skip 1 + Find-Matches (Get-ZLocation) $arguments | Get-EscapedPath + } + default { + if (Test-Path Function:\PreZTabExpansion) { + PreZTabExpansion $line $lastWord + } + } + } +} +# +# End of tab completion. +# + +function Set-ZLocation() +{ + if (-not $args) { + $args = @() + } + $matches = Find-Matches (Get-ZLocation) $args + if ($matches) { + Push-Location ($matches | Select-Object -First 1) + } else { + Write-Warning "Cannot find matching location" + } +} + + +Set-Alias -Name z -Value Set-ZLocation +Export-ModuleMember -Function Set-ZLocation, Get-ZLocation -Alias z \ No newline at end of file diff --git a/samples/PowerShell/hello.ps1 b/samples/PowerShell/hello.ps1 deleted file mode 100644 index eca1e76c..00000000 --- a/samples/PowerShell/hello.ps1 +++ /dev/null @@ -1,2 +0,0 @@ -# Hello world in powershell -Write-Host 'Hello World' \ No newline at end of file diff --git a/samples/PowerShell/hello.psm1 b/samples/PowerShell/hello.psm1 deleted file mode 100644 index 3db82f01..00000000 --- a/samples/PowerShell/hello.psm1 +++ /dev/null @@ -1,5 +0,0 @@ -# Hello World powershell module - -function hello() { - Write-Host 'Hello World' -} \ No newline at end of file diff --git a/samples/PowerShell/history.ps1 b/samples/PowerShell/history.ps1 new file mode 100644 index 00000000..3161a3cb --- /dev/null +++ b/samples/PowerShell/history.ps1 @@ -0,0 +1,65 @@ +function Save-HistoryAll() { + $history = Get-History -Count $MaximumHistoryCount + [array]::Reverse($history) + $history = $history | Group CommandLine | Foreach {$_.Group[0]} + [array]::Reverse($history) + $history | Export-Csv $historyPath +} + +function Save-HistoryIncremental() { +# Get-History -Count $MaximumHistoryCount | Group CommandLine | Foreach {$_.Group[0]} | Export-Csv $historyPath + Get-History -Count 1 | Export-Csv -Append $historyPath +} + +# hook powershell's exiting event & hide the registration with -supportevent. +#Register-EngineEvent -SourceIdentifier powershell.exiting -SupportEvent -Action { Save-History } + +$oldPrompt = Get-Content function:\prompt + +if( $oldPrompt -notlike '*Save-HistoryIncremental*' ) +{ + $newPrompt = @' +Save-HistoryIncremental + +'@ + $newPrompt += $oldPrompt + $function:prompt = [ScriptBlock]::Create($newPrompt) +} + +# load previous history, if it exists +if ((Test-Path $historyPath)) { + $loadTime = + ( + Measure-Command { + Import-Csv $historyPath | Add-History + Save-HistoryAll + Clear-History + Import-Csv $historyPath | ? {$count++;$true} | Add-History + } + ).totalseconds + Write-Host -Fore Green "`nLoaded $count history item(s) in $loadTime seconds.`n" +} + + +function Search-History() +{ + <# + .SYNOPSIS + Retrive and filter history based on query + .DESCRIPTION + .PARAMETER Name + .EXAMPLE + .LINK + #> + + param( + [string[]] $query + ) + + $history = Get-History -Count $MaximumHistoryCount + foreach ($item in $query){ + $item = $item.ToLower() + $history = $history | where {$_.CommandLine.ToLower().Contains($item)} + } + $history +} \ No newline at end of file diff --git a/samples/desktop/example.desktop b/samples/desktop/example.desktop new file mode 100644 index 00000000..81221d99 --- /dev/null +++ b/samples/desktop/example.desktop @@ -0,0 +1,21 @@ +# http://standards.freedesktop.org/desktop-entry-spec/latest/apa.html + +[Desktop Entry] +Version=1.0 +Type=Application +Name=Foo Viewer +Comment=The best viewer for Foo objects available! +TryExec=fooview +Exec=fooview %F +Icon=fooview +MimeType=image/x-foo; +Actions=Gallery;Create; + +[Desktop Action Gallery] +Exec=fooview --gallery +Name=Browse Gallery + +[Desktop Action Create] +Exec=fooview --create-new +Name=Create a new Foo! +Icon=fooview-new \ No newline at end of file diff --git a/samples/eC/Designer.ec b/samples/eC/Designer.ec new file mode 100644 index 00000000..38ca035f --- /dev/null +++ b/samples/eC/Designer.ec @@ -0,0 +1,337 @@ +import "ide" + +class Designer : DesignerBase +{ + ~Designer() + { + if(GetActiveDesigner() == this) + { + SetActiveDesigner(null); + } + if(classDesigner) + delete classDesigner; + } + + // *** DesignerBase Implementation *** + + void ModifyCode() + { + codeEditor.ModifyCode(); + } + + void UpdateProperties() + { + codeEditor.DesignerModifiedObject(); + } + + void CodeAddObject(Instance instance, ObjectInfo * object) + { + codeEditor.AddObject(instance, object); + } + + void SheetAddObject(ObjectInfo object) + { + codeEditor.sheet.AddObject(object, object.name, typeData, true); //className, true); + } + + void AddToolBoxClass(Class _class) + { + ((IDEWorkSpace)master).toolBox.AddControl(_class); + } + + void AddDefaultMethod(Instance instance, Instance classInstance) + { + Class _class = instance._class; + Method defaultMethod = null; + + for( ; _class; _class = _class.base) + { + Method method; + int minID = MAXINT; + for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next) + { + if(method.type == virtualMethod) + { + if(!method.dataType) + method.dataType = ProcessTypeString(method.dataTypeString, false); + if(method.vid < minID && (instance == classInstance || (method.dataType.thisClass && eClass_IsDerived(classInstance._class, method.dataType.thisClass.registered)))) + { + defaultMethod = method; + minID = method.vid; + } + } + } + if(defaultMethod) + break; + } + codeEditor.AddMethod(defaultMethod); + } + + bool ObjectContainsCode(ObjectInfo object) + { + // Confirmation if control contains code + if(object.instCode) + { + MembersInit members; + if(object.instCode.members) + { + for(members = object.instCode.members->first; members; members = members.next) + { + if(members.type == methodMembersInit) + { + //if(!Code_IsFunctionEmpty(members.function)) + { + return true; + } + } + } + } + } + return false; + } + + void DeleteObject(ObjectInfo object) + { + if(codeEditor) + codeEditor.DeleteObject(object); + } + + void RenameObject(ObjectInfo object, const char * name) + { + if(object && (name || !object.classDefinition)) + codeEditor.RenameObject(object, name); + } + + bool FindObject(Instance * object, const char * string) + { + ObjectInfo classObject; + for(classObject = codeEditor.classes.first; classObject; classObject = classObject.next) + { + ObjectInfo check; + if(classObject.name && !strcmp(string, classObject.name)) + { + *object = classObject.instance; + break; + } + for(check = classObject.instances.first; check; check = check.next) + { + if(check.name && !strcmp(string, check.name)) + { + *object = check.instance; + break; + } + } + if(check) + return true; + } + return false; + } + + void SelectObjectFromDesigner(ObjectInfo object) + { + codeEditor.SelectObjectFromDesigner(object); + } + + borderStyle = sizable; + isActiveClient = true; + hasVertScroll = true; + hasHorzScroll = true; + hasClose = true; + hasMaximize = true; + hasMinimize = true; + text = $"Designer"; + menu = Menu { }; + anchor = Anchor { left = 300, right = 150, top = 0, bottom = 0 }; + + ToolBox toolBox; + CodeEditor codeEditor; + + Menu fileMenu { menu, $"File", f }; + MenuItem fileSaveItem + { + fileMenu, $"Save", s, ctrlS; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + return codeEditor.MenuFileSave(selection, mods); + } + }; + MenuItem fileSaveAsItem + { + fileMenu, $"Save As...", a; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + return codeEditor.MenuFileSaveAs(selection, mods); + } + }; + bool debugClosing; + + bool OnClose(bool parentClosing) + { + if(!parentClosing) + { + if(codeEditor && codeEditor.inUseDebug && !debugClosing) + { + debugClosing = true; + closing = false; + if(CloseConfirmation(false)) + { + visible = false; + if(modifiedDocument) + OnFileModified({ modified = true }, null); + } + debugClosing = false; + return false; + } + if(codeEditor && !codeEditor.closing && !debugClosing) + { + if(!codeEditor.visible) + { + if(!codeEditor.Destroy(0)) + return false; + else + codeEditor = null; + } + else + { + visible = false; + return false; + } + } + } + return true; + } + + bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct) + { + if(active) + { + codeEditor.EnsureUpToDate(); + codeEditor.fixCaret = true; + /* + if(classDesigner) + classDesigner.Activate(); + */ + } + return true; + } + + bool OnKeyHit(Key key, unichar ch) + { + return codeEditor.sheet.OnKeyHit(key, ch); + } + + watch(modifiedDocument) + { + fileSaveItem.disabled = !modifiedDocument && codeEditor.fileName; + }; + + // *** METHODS ACCESSED FROM PROPERTY SHEET/TOOLBOX/CODE EDITOR *** + void Reset() + { + if(classDesigner) + { + classDesigner.Reset(); + classDesigner.SelectObject(null, null); + classDesigner.Destroy(0); + delete classDesigner; + } + } + + void FillToolBox() + { + if(this && classDesigner) + classDesigner.ListToolBoxClasses(this); + } + + void SelectObject(ObjectInfo object, Instance instance) + { + ClassDesignerBase classDesigner = this.classDesigner; +#ifdef _DEBUG + if(instance && instance._class.module.application != codeEditor.privateModule) + printf("warning: SelectObject: instance._class.module.application != codeEditor.privateModule\n"); +#endif + if(!classDesigner || !instance || classDesigner._class != (Class)eInstance_GetDesigner(instance)) + { + if(classDesigner) + { + classDesigner.SelectObject(null, null); + classDesigner.Destroy(0); + classDesigner = null; + delete this.classDesigner; + } + if(instance) + { + this.classDesigner = classDesigner = eInstance_New(eInstance_GetDesigner(instance)); + incref classDesigner; + //if(!classDesigner.parent) + { + classDesigner.parent = this; + classDesigner.anchor = Anchor { left = 0, right = 0, top = 0, bottom = 0 }; + } + classDesigner.Create(); + } + } + // Call class editor SelectObject + if(classDesigner) + classDesigner.SelectObject(object, instance); + } + + void AddObject() + { + // Call class editor AddObject + if(classDesigner) + classDesigner.AddObject(); + if(visible) + Activate(); + else + codeEditor.Activate(); + } + + void CreateObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + + // Call class editor CreateObject + if(designerClass) + designerClass.CreateObject(this, instance, object, isClass, iclass); + } + + void ::PostCreateObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + + // Call class editor PostCreateObject + if(designerClass) + designerClass.PostCreateObject(instance, object, isClass, iclass); + } + + void ::DroppedObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + + // Call class editor PostCreateObject + if(designerClass) + designerClass.DroppedObject(instance, object, isClass, iclass); + } + + void PrepareTestObject(Instance instance) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + if(designerClass) + designerClass.PrepareTestObject(this, instance); + } + + void ::DestroyObject(Instance instance) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + if(designerClass) + designerClass.DestroyObject(instance); + } + + void ::FixProperty(Property prop, Instance instance) + { + subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance); + if(designerClass) + designerClass.FixProperty(prop, instance); + } +} diff --git a/test/fixtures/Data/Modelines/example_smalltalk.md b/test/fixtures/Data/Modelines/example_smalltalk.md new file mode 100644 index 00000000..edf4bc13 --- /dev/null +++ b/test/fixtures/Data/Modelines/example_smalltalk.md @@ -0,0 +1 @@ +; -*-mode:Smalltalk-*- diff --git a/test/fixtures/Data/Modelines/iamphp.inc b/test/fixtures/Data/Modelines/iamphp.inc new file mode 100644 index 00000000..9e67098e --- /dev/null +++ b/test/fixtures/Data/Modelines/iamphp.inc @@ -0,0 +1 @@ +; -*- MoDe: PhP;-*- diff --git a/test/fixtures/Data/Modelines/not_perl.pl b/test/fixtures/Data/Modelines/not_perl.pl new file mode 100644 index 00000000..39e38958 --- /dev/null +++ b/test/fixtures/Data/Modelines/not_perl.pl @@ -0,0 +1,3 @@ +/* vim: set filEtype=pRoloG: */ + +# I am Prolog diff --git a/test/fixtures/Data/Modelines/ruby b/test/fixtures/Data/Modelines/ruby new file mode 100644 index 00000000..9dee00eb --- /dev/null +++ b/test/fixtures/Data/Modelines/ruby @@ -0,0 +1,3 @@ +/* vim: set filetype=ruby: */ + +# I am Ruby diff --git a/test/fixtures/Data/Modelines/seeplusplus b/test/fixtures/Data/Modelines/seeplusplus new file mode 100644 index 00000000..a5cdd9d3 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplus @@ -0,0 +1,3 @@ +/* vim: set ft=cpp: */ + +I would like to be C++ please. diff --git a/test/helper.rb b/test/helper.rb index ebfeefc7..a6a03672 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -2,3 +2,21 @@ require "bundler/setup" require "minitest/autorun" require "mocha/setup" require "linguist" + +def fixtures_path + File.expand_path("../fixtures", __FILE__) +end + +def fixture_blob(name) + name = File.join(fixtures_path, name) unless name =~ /^\// + Linguist::FileBlob.new(name, fixtures_path) +end + +def samples_path + File.expand_path("../../samples", __FILE__) +end + +def sample_blob(name) + name = File.join(samples_path, name) unless name =~ /^\// + Linguist::FileBlob.new(name, samples_path) +end diff --git a/test/test_blob.rb b/test/test_blob.rb index 4c4f7978..ceb54bb3 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -14,24 +14,6 @@ class TestBlob < Minitest::Test Encoding.default_external = @original_external end - def samples_path - File.expand_path("../../samples", __FILE__) - end - - def fixtures_path - File.expand_path("../fixtures", __FILE__) - end - - def sample_blob(name) - name = File.join(samples_path, name) unless name =~ /^\// - FileBlob.new(name, samples_path) - end - - def fixture_blob(name) - name = File.join(fixtures_path, name) unless name =~ /^\// - FileBlob.new(name, fixtures_path) - end - def script_blob(name) blob = sample_blob(name) blob.instance_variable_set(:@name, 'script') @@ -251,7 +233,8 @@ class TestBlob < Minitest::Test assert sample_blob("Zephir/filenames/exception.zep.php").generated? assert !sample_blob("Zephir/Router.zep").generated? - assert sample_blob("node_modules/grunt/lib/grunt.js").generated? + + assert Linguist::Generated.generated?("node_modules/grunt/lib/grunt.js", nil) # Godep saved dependencies assert sample_blob("Godeps/Godeps.json").generated? @@ -291,8 +274,6 @@ class TestBlob < Minitest::Test assert sample_blob("deps/http_parser/http_parser.c").vendored? assert sample_blob("deps/v8/src/v8.h").vendored? - assert sample_blob("tools/something/else.c").vendored? - # Chart.js assert sample_blob("some/vendored/path/Chart.js").vendored? assert !sample_blob("some/vendored/path/chart.js").vendored? @@ -303,9 +284,6 @@ class TestBlob < Minitest::Test # Debian packaging assert sample_blob("debian/cron.d").vendored? - # Erlang - assert sample_blob("rebar").vendored? - # Minified JavaScript and CSS assert sample_blob("foo.min.js").vendored? assert sample_blob("foo.min.css").vendored? @@ -314,9 +292,6 @@ class TestBlob < Minitest::Test assert !sample_blob("foomin.css").vendored? assert !sample_blob("foo.min.txt").vendored? - #.osx - assert sample_blob(".osx").vendored? - # Prototype assert !sample_blob("public/javascripts/application.js").vendored? assert sample_blob("public/javascripts/prototype.js").vendored? @@ -324,9 +299,6 @@ class TestBlob < Minitest::Test assert sample_blob("public/javascripts/controls.js").vendored? assert sample_blob("public/javascripts/dragdrop.js").vendored? - # Samples - assert sample_blob("Samples/Ruby/foo.rb").vendored? - # jQuery assert sample_blob("jquery.js").vendored? assert sample_blob("public/javascripts/jquery.js").vendored? diff --git a/test/test_classifier.rb b/test/test_classifier.rb index 1d10d512..2ae2f45e 100644 --- a/test/test_classifier.rb +++ b/test/test_classifier.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestClassifier < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def fixture(name) File.read(File.join(samples_path, name)) end diff --git a/test/test_generated.rb b/test/test_generated.rb index 1c3f8d90..b714e19e 100644 --- a/test/test_generated.rb +++ b/test/test_generated.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestGenerated < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - class DataLoadedError < StandardError; end def generated_without_loading_data(name) diff --git a/test/test_heuristics.rb b/test/test_heuristics.rb index 7520e828..3ea4af78 100644 --- a/test/test_heuristics.rb +++ b/test/test_heuristics.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestHeuristcs < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def fixture(name) File.read(File.join(samples_path, name)) end @@ -133,6 +129,20 @@ class TestHeuristcs < Minitest::Test }) end + def test_lsp_by_heuristics + assert_heuristics({ + "Common Lisp" => all_fixtures("Common Lisp"), + "NewLisp" => all_fixtures("NewLisp") + }) + end + + def test_cs_by_heuristics + assert_heuristics({ + "C#" => all_fixtures("C#", "*.cs"), + "Smalltalk" => all_fixtures("Smalltalk", "*.cs") + }) + end + def assert_heuristics(hash) candidates = hash.keys.map { |l| Language[l] } diff --git a/test/test_modelines.rb b/test/test_modelines.rb new file mode 100644 index 00000000..6c68cc87 --- /dev/null +++ b/test/test_modelines.rb @@ -0,0 +1,25 @@ +require_relative "./helper" + +class TestModelines < Minitest::Test + include Linguist + + def assert_modeline(language, blob) + assert_equal language, Linguist::Strategy::Modeline.call(blob).first + end + + def test_modeline_strategy + assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplus") + assert_modeline Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl") + assert_modeline Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md") + assert_modeline Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc") + end + + def test_modeline_languages + assert_equal Language["Ruby"], fixture_blob("Data/Modelines/ruby").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplus").language + assert_equal Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl").language + assert_equal Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md").language + assert_equal Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc").language + end +end diff --git a/test/test_tokenizer.rb b/test/test_tokenizer.rb index 24a74105..780db019 100644 --- a/test/test_tokenizer.rb +++ b/test/test_tokenizer.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestTokenizer < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def tokenize(data) data = File.read(File.join(samples_path, data.to_s)) if data.is_a?(Symbol) Tokenizer.tokenize(data) @@ -41,6 +37,8 @@ class TestTokenizer < Minitest::Test assert_equal %w(foo), tokenize("foo {- Comment -}") assert_equal %w(foo), tokenize("foo (* Comment *)") assert_equal %w(%), tokenize("2 % 10\n% Comment") + assert_equal %w(foo bar), tokenize("foo\n\"\"\"\nComment\n\"\"\"\nbar") + assert_equal %w(foo bar), tokenize("foo\n'''\nComment\n'''\nbar") end def test_sgml_tags diff --git a/vendor/grammars/AutoHotkey b/vendor/grammars/AutoHotkey index a2207359..9b42c86e 160000 --- a/vendor/grammars/AutoHotkey +++ b/vendor/grammars/AutoHotkey @@ -1 +1 @@ -Subproject commit a2207359782c564a9a3bfe5142d7b5a250d9b18b +Subproject commit 9b42c86e75a78e0f3c37d87476c1d943803fa76e diff --git a/vendor/grammars/CLIPS-sublime b/vendor/grammars/CLIPS-sublime new file mode 160000 index 00000000..f6904baa --- /dev/null +++ b/vendor/grammars/CLIPS-sublime @@ -0,0 +1 @@ +Subproject commit f6904baa78b8b918a7815f4f467fe0ab51c38972 diff --git a/vendor/grammars/Creole b/vendor/grammars/Creole new file mode 160000 index 00000000..bac4656c --- /dev/null +++ b/vendor/grammars/Creole @@ -0,0 +1 @@ +Subproject commit bac4656c8d2a000d6c5940a3d3798a856e44396f diff --git a/vendor/grammars/G-Code b/vendor/grammars/G-Code new file mode 160000 index 00000000..81e8b03e --- /dev/null +++ b/vendor/grammars/G-Code @@ -0,0 +1 @@ +Subproject commit 81e8b03e3dc71f2c8eddfb389dbda21a320f45c1 diff --git a/vendor/grammars/GDScript-sublime b/vendor/grammars/GDScript-sublime new file mode 160000 index 00000000..99a0d512 --- /dev/null +++ b/vendor/grammars/GDScript-sublime @@ -0,0 +1 @@ +Subproject commit 99a0d512248fb85741b00d9d702cf97797de9a4c diff --git a/vendor/grammars/Handlebars b/vendor/grammars/Handlebars index 87669eb0..7bbedb02 160000 --- a/vendor/grammars/Handlebars +++ b/vendor/grammars/Handlebars @@ -1 +1 @@ -Subproject commit 87669eb08dc58f6237f0c884774dc387a9e5e9da +Subproject commit 7bbedb02585912c6e89bec59621aaf2950c28a09 diff --git a/vendor/grammars/JSyntax b/vendor/grammars/JSyntax new file mode 160000 index 00000000..74971149 --- /dev/null +++ b/vendor/grammars/JSyntax @@ -0,0 +1 @@ +Subproject commit 74971149b5926f800b8eb157925a1670a57846b4 diff --git a/vendor/grammars/Modelica b/vendor/grammars/Modelica new file mode 160000 index 00000000..d7e50e39 --- /dev/null +++ b/vendor/grammars/Modelica @@ -0,0 +1 @@ +Subproject commit d7e50e39c14a49153d3c17dfbd623258cf1a5d69 diff --git a/vendor/grammars/NimLime b/vendor/grammars/NimLime index a7067c60..75811539 160000 --- a/vendor/grammars/NimLime +++ b/vendor/grammars/NimLime @@ -1 +1 @@ -Subproject commit a7067c605b893585c056d32a20a1b953f100e138 +Subproject commit 75811539ec1a32e72821a540e1ef73fce0febd43 diff --git a/vendor/grammars/SCSS.tmbundle b/vendor/grammars/SCSS.tmbundle index 41475020..49a74571 160000 --- a/vendor/grammars/SCSS.tmbundle +++ b/vendor/grammars/SCSS.tmbundle @@ -1 +1 @@ -Subproject commit 41475020634fc07b5c03ff0dfaee64c2491fa32b +Subproject commit 49a74571e7346b082016168fd702d41d1d319727 diff --git a/vendor/grammars/Sublime-Inform b/vendor/grammars/Sublime-Inform index c52a11e5..8db129b8 160000 --- a/vendor/grammars/Sublime-Inform +++ b/vendor/grammars/Sublime-Inform @@ -1 +1 @@ -Subproject commit c52a11e50697897469c9ad7c7a59dfdb683db654 +Subproject commit 8db129b8389044a6660ca232566651c8fe3ab646 diff --git a/vendor/grammars/Sublime-Text-2-OpenEdge-ABL b/vendor/grammars/Sublime-Text-2-OpenEdge-ABL index 7b02e1e2..6e8231cc 160000 --- a/vendor/grammars/Sublime-Text-2-OpenEdge-ABL +++ b/vendor/grammars/Sublime-Text-2-OpenEdge-ABL @@ -1 +1 @@ -Subproject commit 7b02e1e2444febb7c6b2179d52de0d2a7cdf5d58 +Subproject commit 6e8231cca124750b413ee50e8a4ee20e36636a03 diff --git a/vendor/grammars/TXL b/vendor/grammars/TXL new file mode 160000 index 00000000..c1c98dfa --- /dev/null +++ b/vendor/grammars/TXL @@ -0,0 +1 @@ +Subproject commit c1c98dfa86a8510532aee3df99181f9e0487fee8 diff --git a/vendor/grammars/asp.tmbundle b/vendor/grammars/asp.tmbundle index e2c72903..144b2108 160000 --- a/vendor/grammars/asp.tmbundle +++ b/vendor/grammars/asp.tmbundle @@ -1 +1 @@ -Subproject commit e2c72903175d4211e4c698a5fa635cc443405892 +Subproject commit 144b21081aa53b8856f839aea68a724312f6001d diff --git a/vendor/grammars/ats.sublime b/vendor/grammars/ats.sublime new file mode 160000 index 00000000..d954ef6b --- /dev/null +++ b/vendor/grammars/ats.sublime @@ -0,0 +1 @@ +Subproject commit d954ef6b27dbdbed6276c7b9b63d3a39d9f69a2c diff --git a/vendor/grammars/carto-atom b/vendor/grammars/carto-atom index 8086625a..c00fb6c4 160000 --- a/vendor/grammars/carto-atom +++ b/vendor/grammars/carto-atom @@ -1 +1 @@ -Subproject commit 8086625aa5deac4ccd7374644b89e715deec2f7f +Subproject commit c00fb6c461e17de53e9efaf5b495e5b7d877b9d6 diff --git a/vendor/grammars/ceylon-sublimetext b/vendor/grammars/ceylon-sublimetext index a81ad702..07029801 160000 --- a/vendor/grammars/ceylon-sublimetext +++ b/vendor/grammars/ceylon-sublimetext @@ -1 +1 @@ -Subproject commit a81ad702b450a440c9d366fd2e128ea6a895dabd +Subproject commit 070298013e732cc7233c5169181a4a65c0ad6ef9 diff --git a/vendor/grammars/dart-sublime-bundle b/vendor/grammars/dart-sublime-bundle index d14f6469..fecdbc5f 160000 --- a/vendor/grammars/dart-sublime-bundle +++ b/vendor/grammars/dart-sublime-bundle @@ -1 +1 @@ -Subproject commit d14f64690cbde6d0bece2670ab385daf89533aea +Subproject commit fecdbc5f246571025bf3d22feb9fd9a260719e02 diff --git a/vendor/grammars/desktop.tmbundle b/vendor/grammars/desktop.tmbundle new file mode 160000 index 00000000..34f9b8ab --- /dev/null +++ b/vendor/grammars/desktop.tmbundle @@ -0,0 +1 @@ +Subproject commit 34f9b8ab985ff7d981661f632eeff6d6c080cea8 diff --git a/vendor/grammars/ec.tmbundle b/vendor/grammars/ec.tmbundle new file mode 160000 index 00000000..b8ec2d32 --- /dev/null +++ b/vendor/grammars/ec.tmbundle @@ -0,0 +1 @@ +Subproject commit b8ec2d32afcaaef5ed7471d80aa4e0cd8717944d diff --git a/vendor/grammars/factor b/vendor/grammars/factor index 2453a785..4ada3288 160000 --- a/vendor/grammars/factor +++ b/vendor/grammars/factor @@ -1 +1 @@ -Subproject commit 2453a785f73429786583684cf729625c7cf7b04b +Subproject commit 4ada3288806d32beaf68e84c079653106e366d5f diff --git a/vendor/grammars/fsharpbinding b/vendor/grammars/fsharpbinding index 99d2e9a5..92d969b1 160000 --- a/vendor/grammars/fsharpbinding +++ b/vendor/grammars/fsharpbinding @@ -1 +1 @@ -Subproject commit 99d2e9a53924ae5ba850985f3df1dc8c11cb6731 +Subproject commit 92d969b19715192928d0c865c87a1aac3ba98dac diff --git a/vendor/grammars/grace-tmbundle b/vendor/grammars/grace-tmbundle new file mode 160000 index 00000000..c342d35c --- /dev/null +++ b/vendor/grammars/grace-tmbundle @@ -0,0 +1 @@ +Subproject commit c342d35c76d6a7dd5cd91157ca5b39481ef59e96 diff --git a/vendor/grammars/haxe-sublime-bundle b/vendor/grammars/haxe-sublime-bundle index e2613bb1..50c5aa0e 160000 --- a/vendor/grammars/haxe-sublime-bundle +++ b/vendor/grammars/haxe-sublime-bundle @@ -1 +1 @@ -Subproject commit e2613bb12598d4ae2de5ba57af890ce910195fce +Subproject commit 50c5aa0e10f277f83dfe3d0e269a1043271be4df diff --git a/vendor/grammars/language-gfm b/vendor/grammars/language-gfm index 6af44a08..18400b22 160000 --- a/vendor/grammars/language-gfm +++ b/vendor/grammars/language-gfm @@ -1 +1 @@ -Subproject commit 6af44a08718668035f45270898389ae4fc8eeb8b +Subproject commit 18400b22cd7968afee982b4e0aa57ef7813ce991 diff --git a/vendor/grammars/language-javascript b/vendor/grammars/language-javascript index 51575193..ac37d2a8 160000 --- a/vendor/grammars/language-javascript +++ b/vendor/grammars/language-javascript @@ -1 +1 @@ -Subproject commit 515751937df1d397b495e4a92fec5a0933994cdb +Subproject commit ac37d2a87c14271a23ba754d85b7746594c0d3c8 diff --git a/vendor/grammars/language-python b/vendor/grammars/language-python index 46072e32..0141d449 160000 --- a/vendor/grammars/language-python +++ b/vendor/grammars/language-python @@ -1 +1 @@ -Subproject commit 46072e32e3060eb8e2fea98a106a86db89acc842 +Subproject commit 0141d44946d55ae06ce4dba90b1b0e08db1e437e diff --git a/vendor/grammars/latex.tmbundle b/vendor/grammars/latex.tmbundle index 52b2251a..16154cef 160000 --- a/vendor/grammars/latex.tmbundle +++ b/vendor/grammars/latex.tmbundle @@ -1 +1 @@ -Subproject commit 52b2251aab30577f4b3b3cc8997fb3c7d0e798ce +Subproject commit 16154cef75708eabc5ebd83c61ad49e8830d835d diff --git a/vendor/grammars/liquid.tmbundle b/vendor/grammars/liquid.tmbundle new file mode 160000 index 00000000..c65939f1 --- /dev/null +++ b/vendor/grammars/liquid.tmbundle @@ -0,0 +1 @@ +Subproject commit c65939f11ad9a91b8c4660a357c36660e9a09e6c diff --git a/vendor/grammars/mercury-tmlanguage b/vendor/grammars/mercury-tmlanguage index eaef0b06..1cb8e949 160000 --- a/vendor/grammars/mercury-tmlanguage +++ b/vendor/grammars/mercury-tmlanguage @@ -1 +1 @@ -Subproject commit eaef0b0643b2cea0d7d26056f2dd264c5a652be9 +Subproject commit 1cb8e94922803658040bc29aa732c1671e2afe5b diff --git a/vendor/grammars/nesC.tmbundle b/vendor/grammars/nesC.tmbundle index 5958c490..d0d322ce 160000 --- a/vendor/grammars/nesC.tmbundle +++ b/vendor/grammars/nesC.tmbundle @@ -1 +1 @@ -Subproject commit 5958c490262e4a5a7803d97c9ec770bd40307153 +Subproject commit d0d322ceafe3c4d8affc0e8b767fb6ad65c52704 diff --git a/vendor/grammars/objective-c.tmbundle b/vendor/grammars/objective-c.tmbundle index d66de9b4..8387be89 160000 --- a/vendor/grammars/objective-c.tmbundle +++ b/vendor/grammars/objective-c.tmbundle @@ -1 +1 @@ -Subproject commit d66de9b4fcfcaf53e64cc05fed0cf66c6980c9b2 +Subproject commit 8387be8975e47cd8e4314cb197e4fc2834159807 diff --git a/vendor/grammars/perl.tmbundle b/vendor/grammars/perl.tmbundle index 8f62f3c4..3396190b 160000 --- a/vendor/grammars/perl.tmbundle +++ b/vendor/grammars/perl.tmbundle @@ -1 +1 @@ -Subproject commit 8f62f3c458cacba3152bfedcc971735a0a5d61b1 +Subproject commit 3396190be167310600d00da6ff9af7807cea4b12 diff --git a/vendor/grammars/php.tmbundle b/vendor/grammars/php.tmbundle index d24593d7..1ae104d8 160000 --- a/vendor/grammars/php.tmbundle +++ b/vendor/grammars/php.tmbundle @@ -1 +1 @@ -Subproject commit d24593d75c3c5f01b4b0705a9e6db132c0cfd55b +Subproject commit 1ae104d86b303a7cf8460a4abca2125331b7bab6 diff --git a/vendor/grammars/powershell b/vendor/grammars/powershell new file mode 160000 index 00000000..84fd9726 --- /dev/null +++ b/vendor/grammars/powershell @@ -0,0 +1 @@ +Subproject commit 84fd97265c93abcd52de5915b4cf1179cc508373 diff --git a/vendor/grammars/powershell.tmbundle b/vendor/grammars/powershell.tmbundle deleted file mode 160000 index f8716b43..00000000 --- a/vendor/grammars/powershell.tmbundle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f8716b432eb0a1a6cbc93ee42451a443db844c0f diff --git a/vendor/grammars/ruby-slim.tmbundle b/vendor/grammars/ruby-slim.tmbundle index 07d55270..741ccd56 160000 --- a/vendor/grammars/ruby-slim.tmbundle +++ b/vendor/grammars/ruby-slim.tmbundle @@ -1 +1 @@ -Subproject commit 07d552705b812e6666014c0061bc511736183a86 +Subproject commit 741ccd5620a73dfb35d0d199ab63ee28f63ed70b diff --git a/vendor/grammars/sas.tmbundle b/vendor/grammars/sas.tmbundle index 0d864a6b..aefac510 160000 --- a/vendor/grammars/sas.tmbundle +++ b/vendor/grammars/sas.tmbundle @@ -1 +1 @@ -Subproject commit 0d864a6bc89ca418e9516249774fc9ab7c792a79 +Subproject commit aefac51088df579fec4df0e3d8459f31b461d60f diff --git a/vendor/grammars/standard-ml.tmbundle b/vendor/grammars/standard-ml.tmbundle index af5395b6..791c8b20 160000 --- a/vendor/grammars/standard-ml.tmbundle +++ b/vendor/grammars/standard-ml.tmbundle @@ -1 +1 @@ -Subproject commit af5395b606273b53e7dd3550270cff7f886d3cc3 +Subproject commit 791c8b2054b4c12edcee29d73945c0db53e447e9 diff --git a/vendor/grammars/sublime-apl b/vendor/grammars/sublime-apl new file mode 160000 index 00000000..a8c36775 --- /dev/null +++ b/vendor/grammars/sublime-apl @@ -0,0 +1 @@ +Subproject commit a8c36775d58c9a80f3b7f572cb4fac5976a6af99 diff --git a/vendor/grammars/sublime-golo b/vendor/grammars/sublime-golo new file mode 160000 index 00000000..2c0707bd --- /dev/null +++ b/vendor/grammars/sublime-golo @@ -0,0 +1 @@ +Subproject commit 2c0707bd4fb11ec354d552bfbc6c8c5febdfd1ad diff --git a/vendor/grammars/sublime-rust b/vendor/grammars/sublime-rust index 9609ab44..40df3591 160000 --- a/vendor/grammars/sublime-rust +++ b/vendor/grammars/sublime-rust @@ -1 +1 @@ -Subproject commit 9609ab4418ed6667e06edea83d7fa157827a2923 +Subproject commit 40df35916158b680eb3d9acb9080a03f7799144c diff --git a/vendor/grammars/sublime-text-ox b/vendor/grammars/sublime-text-ox new file mode 160000 index 00000000..bdd03e09 --- /dev/null +++ b/vendor/grammars/sublime-text-ox @@ -0,0 +1 @@ +Subproject commit bdd03e09fabc0b54567136709cdd33d7641b0e19 diff --git a/vendor/grammars/sublimetext-cuda-cpp b/vendor/grammars/sublimetext-cuda-cpp index 3ed68f99..e51269fc 160000 --- a/vendor/grammars/sublimetext-cuda-cpp +++ b/vendor/grammars/sublimetext-cuda-cpp @@ -1 +1 @@ -Subproject commit 3ed68f996137ad684d822463bcda1bfd1de00232 +Subproject commit e51269fc22602d3f7aaac0266fc189c4ed4a3901 diff --git a/vendor/grammars/swift.tmbundle b/vendor/grammars/swift.tmbundle index 3c7eac54..4b3af145 160000 --- a/vendor/grammars/swift.tmbundle +++ b/vendor/grammars/swift.tmbundle @@ -1 +1 @@ -Subproject commit 3c7eac54457aa8f953fa5263cb34ec4dc9555217 +Subproject commit 4b3af145fedd1df488e28e6ae6249530d6a4389c diff --git a/vendor/grammars/text.tmbundle b/vendor/grammars/text.tmbundle index c536e814..961652ad 160000 --- a/vendor/grammars/text.tmbundle +++ b/vendor/grammars/text.tmbundle @@ -1 +1 @@ -Subproject commit c536e81409d1fa1fc24f388f70b0513c3a8bfc59 +Subproject commit 961652ad957678e75b533406de1be5bd7f489063