Sonntag, 9. März 2014

Drehzahl und Vorschub zum Fräsen von Aluminium

Ausgangspunkt meiner Üerlegung war die Frage, ob man mit einer hochwertigen Bohrmaschine auch Aluminum fräsen kann.

Auf den Seiten der Gienger Industrie Service (GIS) findet man eine nützliche Empfehlung zur Berechnung der Geschwindigkeit, mit der man Aluminium fräsen sollte. Die folgende Lisp-Code berechnet die Werte für einen 10 mm Fräser mit zwei Schneiden.

(let* ((vc 200)
       (d1 10)
       (z 2)
       (n (/ (* vc 1000) (* 3.14 d1)))
       (fz (cond ((< d1 5) 0.04)
                 ((< d1 9) 0.05)
                 (t 0.1)))
       (f (* n fz z)))
  (format "Drehzahl n: %.0f U/min  Vorschub f: %.0f mm/s" n (/ f 60)))
Man sollte also mit 6 - 7 Tausend Umdrehungen und 2 cm Vorschub pro Sekunde fräsen. Somit reicht eine einfache Bohrmaschine nicht aus, da die meist nur bis maximal 3 Tausend Umdrehungen drehen. Viele schaffen auch nur die Hälfte und selbst die QUADRILL DR von Festool schafft mit ihren vier Gängen nur maximal 4 Tausend Umdrehungen. Aber zumindest könnte man damit im unteren Ende der GIS-Empfehlung (vc = 125) mit 13 mm Vorschub pro Sekunde fräsen.

Bei Stahl sieht die Sache etwas anders aus.

(let* ((vc 50)
       (d1 10)
       (z 2)
       (n (/ (* vc 1000) (* 3.14 d1)))
       (fz (cond ((< d1 5) 0.02)
                 ((< d1 9) 0.03)
                 (t 0.06)))
       (f (* n fz z)))
  (format "Drehzahl n: %.0f U/min  Vorschub f: %.0f mm/s" n (/ f 60)))
Hier wären nur 1500 Umdrehungen für 3 mm Vorschub nötig. Allerdings ist fraglich, ob das Getriebe das Drehmoment wirklich aushalten würde. Ich denke eher nicht, da es ja eigentlich eine Bohrmaschine ist.

Fazit: zum Fräsen von Aluminum kann man sich mit einer relativ teuren Festool QUADRILL DR behelfen aber in den für weiches Aluminium optimalen Bereich kommt man damit nicht. Für das gleiche Geld bekommt man von Kress sowohl eine Bohrmaschine (650 BS QuiXS) als auch einen Fräser (800 FME).

Mittwoch, 26. Februar 2014

Synchronizing a bold Bash prompt in Debian Terminals

Put the following at the end of the .bashrc file to get a bold prompt:
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w'
if [ "$TERM" = xterm ] ; then
  PS1="\[\e]0;$PS1\a$(tput bold)\]\$? \! $PS1\\$\[$(tput sgr0)\] "
else
  PS1="\[$(tput bold)\]\$? \! $PS1\\$\[$(tput sgr0)\] "
fi
The prompt prints the exit code of the last command, the history id if the current command, the user name, the host name and the working directory.

It is also possible to send the prompt to other systems accessed with SSH. For this it is necessary to export the PS1 environment variable:

export PS1
The SSH daemon of the target system must accept the variable. Put the following line in /etc/ssh/sshd_config:
AcceptEnv PS1
And add the following line to your local SSH configuration in .ssh/config:
SendEnv PS1
After that you have on your local and target system the same prompt without the need to synchronize any bashrc files.

Montag, 10. Februar 2014

Using BSD process accounting to list the memory usage

Sometimes the memory usage of a program is of interest. The following program can be used to list the memory usage reported by the BSD process accounting.
#include <stdio.h>
#include <string.h>
#include <sys/acct.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#define STR(I) #I

int main(int argc, char **argv)
{
  char debian_default[] = "/var/log/account/pacct";
  char usage[] = "Usage: acctmem accounting-file\n";
  char *file;

  if (argc == 2) {
    if (argv[1][0] == '-' && argv[1][1] == 'h') {
      fprintf (stderr, "%s", usage);
      return 0;
    } else {
      file = argv[1];
    }
  }
  else {
    file = debian_default;
  }
  printf ("Using %s\n", file);

  int fd = open (file, O_RDONLY);
  if (fd < 0) {
    perror ("Can not open file");
    return 1;
  }

  struct acct_v3 entry;
  for (;;) {
    ssize_t bytes = read (fd, &entry, sizeof entry);
    if (bytes < 0) {
      perror("Can not read file");
      return 1;
    }
    if (bytes == sizeof entry)
      printf ("%6u: %-" STR(ACCT_COMM) "s(%3u): %uk\n",
       entry.ac_uid,
       (char*)&(entry.ac_comm),
       entry.ac_exitcode,
       entry.ac_mem);
    else
      break;
  }
  return 0;
}
// Local Variables:
// compile-command: "gcc -o acctmem acctmem.c"
// End:

Dienstag, 14. Januar 2014

Apache proxy for CentOS 5 network installation

CentOS 5 provides a network installation image but during the network installation it is not possible to configure a proxy. The following configuration emulates a CentOS mirror with an Apache proxy.
<IfModule mod_proxy.c>
  ProxyPass /centos http://mirror.centos.org/centos
  ProxyPassReverse /centos http://mirror.centos.org/centos
  ProxyRemote * http://proxy:3128
</IfModule>
It is necessary to enable the Apache modules proxy and proxy_http. After that it is possible to start the installation with the IP address of the Apache proxy and the URL /centos/5/os/i386.

Montag, 6. Januar 2014

SSI on Debian

Server Side Includes are an old fashioned way to enable active web server content. Debian provides a module
  /etc/apache2/mods-available/include.load
but lacks a configuration file. This configuration enables SSI for SHTML files.
<IfModule mod_include.c>
  <Location />
    Options +Includes
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
    DirectoryIndex index.shtml
  </Location>
</IfModule>

Dienstag, 3. Dezember 2013

Reading Manifest attributes from a JAR

In C it was common practice to define a program version number in a file called VERSION. In the Make file there was a line which reads the file and stores its in a variable.
VERSION=$(shell cat VERSION)
And later on it was possible to use the variable as a definition argument for the C compiler:
program.o: program.c
	$(CC) -DVERSION=$(VERSION) -o $@
In the code it was possible to craft a version message by the use of this definition.
fprintf (stderr, "program version %s\n", VERSION);

In Java things are much more complicated. It is common practice in Java to store the version number of a program not in the code of the program itself but in the Manifest file of the JAR, which contains the program. The correct manifest attribute is call Implementation-Version. But there is no simple way to reference the Manifest attributes in a program. Instead it is necessary to calculate a resource URL for the Manifest file based on a class, which is in the same JAR. This URL can be opened as a stream and this stream can be used to parse the contents of the Manifest. The following example shows the class ManifestAttributes, which does this.

class manifest
{
  static int n = 0;
  static void debug (Object message)
  {
    System.err.println ("#" + n + "# " + message);
    n = n + 1;
  }

  public static class ManifestAttributes
  {
    private java.util.jar.Attributes attributes;

    public ManifestAttributes ()
    {
      Class this_class = ManifestAttributes.class;
      String class_name = this_class.getName();
      String class_path = class_name.replace (".", "/") + ".class";
      String class_url = this_class.getResource(class_path).toString();
      String manifest_url = class_url.replace (class_path,
                                               "META-INF/MANIFEST.MF");
      java.io.InputStream stream = null;
      java.util.jar.Manifest manifest;
      try {
        stream = new java.net.URL(manifest_url).openStream();
        manifest = new java.util.jar.Manifest(stream);
      }
      catch (java.io.IOException exception) {
        throw new RuntimeException (exception);
      }
      finally {
        try {
          if (stream != null) stream.close();
        }
        catch (java.io.IOException exception) {
          throw new RuntimeException (exception);
        }
      }
      attributes = manifest.getMainAttributes();
    }

    public String get (String key)
    {
      return attributes.getValue(key);
    }
  }

  public static void main (String[] args)
  {
    ManifestAttributes attributes = new ManifestAttributes();
    debug (attributes.get("Manifest-Version"));
    debug (attributes.get("x"));
  }
}

// Local Variables:
// compile-command: "javac manifest.java && jar cvfe manifest.jar manifest manifest*.class && java -jar manifest.jar"
// End:

Donnerstag, 28. November 2013

Reading Subversion information in scripts

Sometimes it is useful to know something about a Subversion repository. The "svn diff" command for example works only with URLs. If you have to write a wrapper for "svn diff" to perform some standard tasks it is necessary to get the repository URL for a directory. This is possible with the "svn info" command. Some people propose to use grep and sed to parse the output of "svn info". But parsing with grep and sed is often not very reliable, because they search only for string patterns. This makes it for example hard to distinguish a revision number of a commit from a revision number of a entry, because they share the same label.

But Subversion provides a far better option, which makes parsing much easier. The "svn info" command can generate XML output, which can be parsed with "xmllint" and an appropriate XPath expression to get the exact information. The following Bash script is a small wrapper around "svn info --xml" and "xmllint --xpath".

#! /bin/bash
if [ "$2" ] ; then
    TARGET=$1
    shift
else
    TARGET=.
fi
svn info --xml "$TARGET" | 
if [ "$1" ] ; then
    if [ '@' = $(cut -c 1 <<<$(basename "$1")) ] ; then
        xmllint --xpath 'string('"$1"')' -
    else
        xmllint --xpath "$1"'/text()' -
    fi
    echo
else
    xmllint --format -
fi

The script makes it quite easy to get the right information:

trunk$ svninfo /info/entry/@revision
2647
trunk$ svninfo /info/entry/commit/@revision
2646
Running the script without any argument pretty prints the raw XML date. This is useful to write the exact XPath expression.