Monday, 16 May 2016

Threads and IPC - Joe Tubbritt

This is intended to be a brief explanation of Threads and IPC that were used in the Lampbotics team project.

A thread is the basic unit of execution of an RTOS. It is essentially a mini self-contained program. Threads are used inside of processes, and multiple threads can be run at the same time. This gives the RTOS the illusion of Real-Time as each thread is switched between at a fast rate. Threads use the system tick timer to enable interrupts that enable switching between them. A thread is designated its own variable(s) as a handle, and used for that threads activity.

For our thread operation, a background thread created by Kamil is used to keep track of the “house-keeping” of all the threads. Our threads that we wrote are essentially user-level threads.

Each thread is assigned a tag and an output. These are assigned using  self.registerOutput( ). For my thread, I am using two tags and outputs: headPosition and lampPosition. The headPosition tag is used to output values to the servo’s on the head i.e. pan and tilt. The lampPosition tag is used to output values to the servo for the up/down movement of the lamp. X,Y, and Z coordinates from Philip’s thread are converted to normalised values for Servo Hat and then assigned to each tag.


import time

# import from parent directory
import sys
import os.path 

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))

import DynamicObjectV2
Obj = DynamicObjectV2.Class

# put your imports here
#setup position variables
Position_x = 0;
Position_y = 0;
Position_z = 0;

def init(self):
    # put your self.registerOutput here
    self.registerOutput("headPosition", Obj("x", 0, "y", 0))
    self.registerOutput("lampPosition", Obj("z",0))

def run (self):
    # put your init and global variables here    
    # main loop
    while 1:
        faceDet = self.getInputs().faceDet
        facecount = faceDet.Face;
        if facecount == True:              
            # calculations
            facePos = self.getInputs().facePos
            Position_x = facePos.x;
            Position_y = facePos.y;
            Position_z = facePos.z;
            self.message("facePos: {}".format(Obj("x", Position_x, "y", Position_y, "z", Position_z)))
            headPosition = Obj("x", 0.0083333*Position_x, "y", 0.010752*Position_y) # values are normalised to 1
            lampTemp = (0.00666666*Position_z)
            lampPosition = (lampTemp)
            # output
            self.output("headPosition", headPosition)
            self.output("lampPosition", Obj("z", lampPosition))

            # if you want to limit framerate, put it at the end

Inter Process Communications:

Inter Process Communications (IPC) is essentially the mechanism used to allow processes to share data. The background thread created by Kamil knows each of the tags and outputs associated with each thread, but not all of the threads know every tag. The threads that are required to interact with other (Face detection and servo position for example), know of each other’s tags and outputs. This is accomplished by using the self.getInputs().faceDet, in my code at least. This enables two separate threads to communicate, which may not necessarily be contained in the same process.

Joe Blog #8

No comments:

Post a Comment