Skip to content

Commit

Permalink
Released alpha version
Browse files Browse the repository at this point in the history
  • Loading branch information
erikliland committed Apr 18, 2015
1 parent 21d64e6 commit b96b42e
Show file tree
Hide file tree
Showing 10 changed files with 858 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# TTK4145-Simulator
Simulator of the elevator model at "Sanntidssalen" at NTNU

How to use:
The simulator core have the same interface as the driver in this rep. The driver wraps Go-calls to C-calls and imports Comedi.

Recomended way to implement:
Set up the elevator program on the lab with the driver/wraper. Then edit the import statement from "driver" to "simulator". The simulator should start and self initialise. When you need to button press commands, you need to start the simulatorInterface.go. This program sends buttoncommands from the keyboard to the simulator core. The buttons are mapped from Z->V on internal orders, Q->E for external orders Up, and S->F for external orders Down.
91 changes: 91 additions & 0 deletions simulatorInterface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package main

// export GOPATH=/home/eriklil/Documents/TTK4145/Project/
//export GOPATH=/Users/Erik/OneDrive/02\ NTNU/01\ Fag/TTK4145\ Sanntid/TTK4145/Project/
// export GOPATH=$(pwd)/
// export GOPATH=~/

import (
"encoding/json"
"fmt"
"log"
"net"
"os"

"strconv"
. "typedef"
)

func listenForUserInput(userInput chan string) {
for {
var command int
fmt.Scanf("%c", &command)
if (command >= 97) && (command <= 122) {
fmt.Println("Sending: ", string(command))
userInput <- string(command)
} else if command != 10 {
fmt.Println("Rejected: ", string(command))
}
}
}

func UDPTransmitServer(lconn *net.UDPConn, sendChannel chan string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("ERROR in UDPTransmitServer.\nClosing connection.")
lconn.Close()
os.Exit(1)
}
}()
for {
msg := <-sendChannel
networkPack, err := json.Marshal(msg)
if err != nil {
log.Println(err)
}
_, err = lconn.Write(networkPack)
if err != nil {
fmt.Printf("UDPTransmitServer-Simulator:\tError: Sending\n")
panic(err)
}
}
}

func main() {
fmt.Println("Starting Simulator interface")

//Generating recive adress
raddr, err := net.ResolveUDPAddr("udp4", "localhost:"+strconv.Itoa(PortFromInterface))
if err != nil {
fmt.Println("Can not resolve this adress")
log.Println(err)
panic(err)
} else {
fmt.Printf("Sending to:\t %s\n", raddr)
}

//Creating local connection
localTransmitConn, err := net.DialUDP("udp4", nil, raddr)
if err != nil {
fmt.Println("Can not create UDP soccet on this port")
log.Println(err)
panic(err)
} else {
fmt.Println("From:\t\t", localTransmitConn.LocalAddr().String())
}

//Making channels
sendChannel := make(chan string, 10)
userInput := make(chan string)

//Spawning threads
go UDPTransmitServer(localTransmitConn, sendChannel)
go listenForUserInput(userInput)

for {
select {
case char := <-userInput:
sendChannel <- char
}
}
}
48 changes: 48 additions & 0 deletions src/channels/channels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package elev
//in port 4
const PORT4 = 3
const OBSTRUCTION = (0x300+23)
const STOP_BUTTON = (0x300+22)
const BUTTON_COMMAND1 = (0x300+21)
const BUTTON_COMMAND2 = (0x300+20)
const BUTTON_COMMAND3 = (0x300+19)
const BUTTON_COMMAND4 = (0x300+18)
const BUTTON_UP1 = (0x300+17)
const BUTTON_UP2 = (0x300+16)
//in port 1
const PORT1 = 2
const BUTTON_DOWN2 = (0x200+0)
const BUTTON_UP3 = (0x200+1)
const BUTTON_DOWN3 = (0x200+2)
const BUTTON_DOWN4 = (0x200+3)
const SENSOR_FLOOR1 = (0x200+4)
const SENSOR_FLOOR2 = (0x200+5)
const SENSOR_FLOOR3 = (0x200+6)
const SENSOR_FLOOR4 = (0x200+7)
//out port 3
const PORT3 = 3
const MOTORDIR = (0x300+15)
const LIGHT_STOP = (0x300+14)
const LIGHT_COMMAND1 = (0x300+13)
const LIGHT_COMMAND2 = (0x300+12)
const LIGHT_COMMAND3 = (0x300+11)
const LIGHT_COMMAND4 = (0x300+10)
const LIGHT_UP1 = (0x300+9)
const LIGHT_UP2 = (0x300+8)
//out port 2
const PORT2 = 3
const LIGHT_DOWN2 = (0x300+7)
const LIGHT_UP3 = (0x300+6)
const LIGHT_DOWN3 = (0x300+5)
const LIGHT_DOWN4 = (0x300+4)
const LIGHT_DOOR_OPEN = (0x300+3)
const LIGHT_FLOOR_IND2 = (0x300+1)
const LIGHT_FLOOR_IND1 = (0x300+0)
//out port 0
const PORT0 = 1
const MOTOR = (0x100+0)
//non-existing ports (for alignment)
const BUTTON_DOWN1 = -1
const BUTTON_UP4 = -1
const LIGHT_DOWN1 = -1
const LIGHT_UP4 = -1
39 changes: 39 additions & 0 deletions src/driver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Which compiler to use
CC = gcc

# Compiler flags go here.
CFLAGS = -g -Wall

# Linker flags go here.
LDFLAGS = -lcomedi -lm

# list of sources
ELEVSRC = io.c

# program executable file name.
TARGET = lift

# top-level rule, to compile everything.
all: $(TARGET)

# Define all object files.
ELEVOBJ = $(ELEVSRC:.c=.o)

# rule to link the program
$(TARGET): $(ELEVOBJ)
$(CC) $^ -o $@ $(LDFLAGS)

# Compile: create object files from C source files.
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@

# rule for cleaning re-compilable files.
clean:
rm -f $(TARGET) $(ELEVOBJ)

rebuild: clean all

.PHONY: all rebuild clean


#Martin Korsgaard, 2006
62 changes: 62 additions & 0 deletions src/driver/channels.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Channel definitions for elevator control using LibComedi
//
// 2006, Martin Korsgaard
#ifndef __INCLUDE_DRIVER_CHANNELS_H__
#define __INCLUDE_DRIVER_CHANNELS_H__

//in port 4
#define PORT4 3
#define OBSTRUCTION (0x300+23)
#define STOP (0x300+22)
#define BUTTON_COMMAND1 (0x300+21)
#define BUTTON_COMMAND2 (0x300+20)
#define BUTTON_COMMAND3 (0x300+19)
#define BUTTON_COMMAND4 (0x300+18)
#define BUTTON_UP1 (0x300+17)
#define BUTTON_UP2 (0x300+16)

//in port 1
#define PORT1 2
#define BUTTON_DOWN2 (0x200+0)
#define BUTTON_UP3 (0x200+1)
#define BUTTON_DOWN3 (0x200+2)
#define BUTTON_DOWN4 (0x200+3)
#define SENSOR_FLOOR1 (0x200+4)
#define SENSOR_FLOOR2 (0x200+5)
#define SENSOR_FLOOR3 (0x200+6)
#define SENSOR_FLOOR4 (0x200+7)

//out port 3
#define PORT3 3
#define MOTORDIR (0x300+15)
#define LIGHT_STOP (0x300+14)
#define LIGHT_COMMAND1 (0x300+13)
#define LIGHT_COMMAND2 (0x300+12)
#define LIGHT_COMMAND3 (0x300+11)
#define LIGHT_COMMAND4 (0x300+10)
#define LIGHT_UP1 (0x300+9)
#define LIGHT_UP2 (0x300+8)

//out port 2
#define PORT2 3
#define LIGHT_DOWN2 (0x300+7)
#define LIGHT_UP3 (0x300+6)
#define LIGHT_DOWN3 (0x300+5)
#define LIGHT_DOWN4 (0x300+4)
#define LIGHT_DOOR_OPEN (0x300+3)
#define LIGHT_FLOOR_IND2 (0x300+1)
#define LIGHT_FLOOR_IND1 (0x300+0)

//out port 0
#define PORT0 1
#define MOTOR (0x100+0)

//non-existing ports (for alignment)
#define BUTTON_DOWN1 -1
#define BUTTON_UP4 -1
#define LIGHT_DOWN1 -1
#define LIGHT_UP4 -1



#endif //#ifndef __INCLUDE_DRIVER_CHANNELS_H__
37 changes: 37 additions & 0 deletions src/driver/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package driver

/*
#cgo LDFLAGS: -lpthread -lcomedi -lm
#include "io.h"
*/
import (
"C"
"errors"
)

func IOInit() error {
if err := int(C.io_init()); err == 0 {
return errors.New("Could not initialise Comedy!")
}
return nil
}

func IO_set_bit(channel int) {
C.io_set_bit(C.int(channel))
}

func IO_clear_bit(channel int) {
C.io_clear_bit(C.int(channel))
}

func IO_write_analog(channel, value int) {
C.io_write_analog(C.int(channel), C.int(value))
}

func IO_read_bit(channel int) bool {
return bool(int(C.io_read_bit(C.int(channel))) != 0)
}

func IO_read_analog(channel int) int {
return int(C.io_read_analog(C.int(channel)))
}
55 changes: 55 additions & 0 deletions src/driver/io.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Wrapper for libComedi I/O.
// These functions provide and interface to libComedi limited to use in
// the real time lab.
//
// 2006, Martin Korsgaard


#include "io.h"
#include "channels.h"
#include <comedilib.h>


static comedi_t *it_g = NULL;

int io_init() {
int i = 0;
int status = 0;

it_g = comedi_open("/dev/comedi0");

if (it_g == NULL)
return 0;

for (i = 0; i < 8; i++) {
status |= comedi_dio_config(it_g, PORT1, i, COMEDI_INPUT);
status |= comedi_dio_config(it_g, PORT2, i, COMEDI_OUTPUT);
status |= comedi_dio_config(it_g, PORT3, i + 8, COMEDI_OUTPUT);
status |= comedi_dio_config(it_g, PORT4, i + 16, COMEDI_INPUT);
}
return (status == 0);
}

void io_set_bit(int channel) {
comedi_dio_write(it_g, channel >> 8, channel & 0xff, 1);
}

void io_clear_bit(int channel) {
comedi_dio_write(it_g, channel >> 8, channel & 0xff, 0);
}

void io_write_analog(int channel, int value) {
comedi_data_write(it_g, channel >> 8, channel & 0xff, 0, AREF_GROUND, value);
}

int io_read_bit(int channel) {
unsigned int data = 0;
comedi_dio_read(it_g, channel >> 8, channel & 0xff, &data);
return (int)data;
}

int io_read_analog(int channel) {
lsampl_t data = 0;
comedi_data_read(it_g, channel >> 8, channel & 0xff, 0, AREF_GROUND, &data);
return (int)data;
}
13 changes: 13 additions & 0 deletions src/driver/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __INCLUDE_IO_H__
#define __INCLUDE_IO_H__

// Returns 0 on init failure
int io_init();

void io_set_bit(int channel);
void io_clear_bit(int channel);
void io_write_analog(int channel, int value);
int io_read_bit(int channel);
int io_read_analog(int channel);

#endif
Loading

0 comments on commit b96b42e

Please sign in to comment.