Monday, 21 September 2015

ZEUS Safety Shift - Part 1

The 'Safety Shift' was a duty for all PhD. students working on the ZEUS experiment. This involved spending 8 hours at the detector hall, mostly in the control room, 8 floors underground. Although periodically you would take a walk around the site, checking the detector subsystems. The shift change-over times were 12am, 8am and 4pm. Shifts were on a rota and once you'd done 4 days in a row there would usually be a few weeks before your next one.

During a normal evening shift the only other person you'd see would be the shift leader who would be a more senior member of the collaboration. Personally, I think the safety shift had the better deal, at least we got to go and stretch our legs. During data taking the leader would have to be more or less continuously at the run control desk.

I loved the midnight until 8 shift. This was mainly because after about 1am you would have almost exclusive use of the ZEUS compute farm. And I did enjoy a bit the feeling of being stuck in a sci-fi set!

Here is a plan of the DESY site with the location of the experimental halls. ZEUS was located in the South Hall, just next to the Trabrennbahn. The South Hall complex was affectionately called "The Pit".

Scan of the back of the DESY Lageplan

You approached the hall through the Trabrennbahn car park. At midnight in the middle of winter this could be quite a lonely walk.


Once you swiped your entrance card you would enter the courtyard area and proceed through the small blue door into the hall itself.

Taking the lift down to the bottom you find the control room to your left. This picture was taken from the 2007 ZEUS shut down. The monitor at the bottom left was the desk for the safety shift.



The run control station for the shift leader is shown below. This was from a quiet evening in 1999.


If, instead of turning left, you exited straight out of the lift you would enter the main hall. The most obvious sight you'd see here was the Rucksack. This was a 3-story hut containing a large proportion of the trigger electronics. The whole hut was mounted on rails and could be moved to the right (in this picture) during access periods for the detector.

During normal operation, the detector itself was largely hidden from view by concrete shielding and the Rucksack itself. It was located to the left of the Rucksack in the above picture. Here is a view of the side facing the Rucksack.

Cabling between the detector and Rucksack was designed to be flexible and allow movement.


Part of the safety shift was to walk around the all with an eye out for any obvious problems. Professor Jon Butterworth, in his book Smashing Physics, tells of a time someone on safety shift found water dripping out from the concrete shielding. This wasn't the only time water got loose, my sister pointed out a leak from one of the pipes in the hall when I was giving her a tour. Her question was, "Is it supposed to be doing that?" With a significant amount of high voltage cables and delicate instruments around, this was not something to take lightly...

This view back from the top of the Rucksack stairs shows some of the remainder of the hall. (For orientation the lift was through the entrance where the blue doors can just be seen.)

Next time, I'll go into more detail about some of the checks we had to make, as well as visiting some of the (literally) darker corners of the pit.

Thursday, 10 September 2015

Remote Robot Arm

Earlier, I set up the Raspberry Pi to communicate with the Ardunio using a Python script. With this in place I can now start putting things together to make something more interesting; for example, controlling the Robot arm.

The first script itself was very basic, sending a few fixed characters with sleeps. To make this more interactive I need to be able to read characters from the keyboard.

I based my new controller script on an example in the Python FAQ. The main difference to the boilerplate sample is I write the character to the serial port that the Ardunio is listening on.

import termios, fcntl, sys, os, serial

ardiuno = serial.Serial('/dev/ttyUSB0')
fd = sys.stdin.fileno()

# Get state of tty and take a copy
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)

# Turn off echo, line buffering and special character processing
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO

termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            # repr() : Return a string containing a printable
            #    representation of an object
            ardiuno.write(c)
            print "Got character", repr(c)
        except IOError: pass
finally:
    # restore old state
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

    tcntl.fcntl(fd, fcntl.F_SETFL, oldflags)


The Arduino code is based on my original robot arm controller project. The motors are now engaged by bytes read from serial input.

  • o and m : forward and backwards on channel A
  • l and k : forward and backwads on channel B
  • Space ' ' : Stop all movement


// Motor controlled by serial inputs
long ii = 0;
byte inByte;

void setup() {
   // initialise serial comms at 9600 baud
   Serial.begin(9600);
  
   //Setup Channel A
   pinMode(12, OUTPUT);    // Initialise Motor Channel A pin - DIRECTION
   pinMode(9, OUTPUT);     // Initialise Brake Channel A pin - BRAKE

   //Setup Channel B
   pinMode(13, OUTPUT);    // Initialise Motor Channel B pin - DIRECTION
   pinMode(8, OUTPUT);     // Initialise Brake Channel B pin - BRAKE
  
   Serial.println("Started");
}

void loop() {

  while (Serial.available() > 0)
  {
     inByte = Serial.read();
     
     if (inByte > 0)
     {
       Serial.println(inByte);
     }
    
     if (inByte == 108) // 'l'
     {  
       digitalWrite(12, HIGH);  // Establish forward direction of Channel A
       digitalWrite(9, LOW);    // Disengage the break for Channel A
       digitalWrite(8, HIGH);   // Engage the Brake for Channel B
       analogWrite(3,244);      // Spin the motor on Channel A at full speed
     }
     if (inByte == 107) // 'k'
     { 
       digitalWrite(12, LOW);    // Establishes backward direction of Channel A
       digitalWrite(9, LOW);     // Disengage the Brake for Channel A
       digitalWrite(8, HIGH);    // Engage the Brake for Channel B
       analogWrite(3, 244);      // Spin the motor on Channel A at half speed
      }
      if (inByte == 111) //'o'
      {
        // digitalWrite(13,HIGH);
        digitalWrite(13, HIGH);  // Establish forward direction of Channel B
        digitalWrite(8, LOW);    // Disengage the break for Channel B
        digitalWrite(9, HIGH);   // Engage the Brake for Channel A
        analogWrite(11,244);     // Spin the motor on Channel B at full speed   
      }
    
      if (inByte == 109 ) //'m'
      {
        // digitalWrite(13,LOW);
        digitalWrite(13, LOW);    // Establishes backward direction of Channel B
        digitalWrite(8, LOW);     // Disengage the Brake for Channel B 
        digitalWrite(9, HIGH);    // Engage the Brake for Channel A
        analogWrite(11, 244);     // Spins the motor on Channel B at half speed
      }
    
      if (inByte == 32) //' '
      {
        digitalWrite(8, HIGH);    // Engage the Brake for Channel B
        digitalWrite(9, HIGH);    // Engage the Brake for Channel A  
      }
   }

}

That's really all there is to it. It's amazing what can be done with such a small amount of code! 

To move the Robot, I log on to the Raspberry Pi using VNC from the laptop. Then run the python script and hit the control keys to engage (or stop!) the motors. As I'm connecting to the Raspberry Pi over wifi, there is no need for the control to be near the robot.

Of course with only a dual channel motor controller I've not got much flexibility in what I can do with the arm but I hope to add another ardunio/controller.

Here is the completed set-up.