Sunteți pe pagina 1din 100

Code document:

Muticore embedded robot

Jasper Maes 3rd Bachelor Computer Science Enrollment: 89619 jasper.maes@vub.ac.be

May 22, 2011

Muticore embedded robot Jasper Maes 3rd Bachelor Computer Science Enrollment: 89619 jasper.maes@vub.ac.be May 22, 2011

Contents

1

Introduction

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

3

1.1 Purpose

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

3

1.2 Scope

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

3

1.3 References .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

3

2

Code created by others .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

2.1 RXTX .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

2.2 TimedKeyListener

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

2.3 Swing

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

3

Most important code .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

3.1 Graphical User Interface

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

4

3.2 Robotcontroller

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

5

4

Description of Code

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

6

4.1 Graphical User Interface

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

6

4.2 Robotcontroller

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

7

5

Code Listings

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

8

5.1 Graphical User Interface

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

8

5.2 Robotcontroller

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

55

Date

Version

 

Description

   

14

May 2011

First draft

 

Setup document and code Added first descriptions of the code Completed describing all components, added scope Editing the descriptions and correcting minor mistakes Final spell checking Code update and minor changes Included latest bugfixes in the code listing

15

May 2011

Second draft

 

16

May 2011

Third draft

 

17

May 2011

Fourth Draft

 

18

May 2011

Fifth Draft

 

21

May 2011

Release candidate

22

May 2011

Final version

 

Change Log

1

1

Introduction

1.1 Purpose

This document shows how all components or entities in the project were implemented. These entities are determined by the requirements from the specifications document[5]. First, an overview is given of the libraries we used that were created by others. Followed by a description of the most important components of both the graphical user interface and the robot control program. After that, all other components are described briefly. The last part of the document consists of all code that was written for the project. Every section is divided in two parts. These parts correspond to the two parts of the project, the graphical user interface and the robot control program.

1.2 Scope

With this project we will implement a robot, using a multicore embedded device[9]. The user will be able to control and steer the robot using a remote control. The robot will use sensors to be aware of its environment and respond appropriately. For example, if the user wants to drive the robot into a wall, it will stop before hitting the wall.

1.3 References

[1] Anonymous. Bug #4153069. http://bugs.sun.com/view_bug.do?bug_id=4153069, June

1998.

[2] Eric J. Braude and Michael E. Bernstein. Software Engineering: Modern Approaches. Wiley, second edition, 2011. ISBN 978-0-471-69208-9.

[3] Jasper Maes. Documentation graphical user interface. guiDocs/, May 2011.

[4] Jasper Maes. Documentation robot controller program. http://artoo.rave.org/public/ robotControllerDocs/, May 2011.

[5] Jasper Maes. Specifications document: Multicore embedded robot. org/public/specifications.pdf, January 2011.

[6] Jasper Maes. Technical document: Multicore embedded robot. http://artoo.rave.org/ public/technical.pdf, March 2011.

[7] Sun

Microsystems.

Java

SE

desktop

overview.

[8] Oracle.

Class serialport.

[9] Christophe Scholliers.

Multicore embedded robot.

ProjectProposal.html, October 2010.

2

2

Code created by others

2.1 RXTX

The RXTX library is used in the control program to allow the program to communicate with the robot using a wireless Zigbee connection. It is a popular library that is also used in the IDE used to program an Arduino to connect to a device using a serial port. The programmer will be notified of new data in an event based approach. The programmer can also choose which signals can trigger an event. This can be a parity error or a frame error but in this project it was sufficient to only use the data available signal. The implementation of RXTX is based on the abstract SerialPort class in the Java API. The documentation of this class can be found on the Oracle website[8].

2.2 TimedKeyListener

This class is used to correct a bug in the original Java implementation of the KeyListener. Instead of calling the keyReleased signal once, when the key is released, it is fired repeatedly, along with the keyTyped or keyPressed signal. This behavior only occurs on the Linux platform. Instead of directly extending the KeyListener class, we extend the TimedKeyListener which provides the correct functionality. Other platforms can use this implementation too even if the original implementation is correct.

2.3 Swing

The Swing libraries were used to create the graphical user interface. These libraries are based on the older, AWT libraries. The biggest improvement of Swing over AWT is the ability to create cross-platform applications. More information can be found on the Swing website [7].

3 Most important code

Both subsections describe the most important components in that part of the program. All components are required to make the program look and work the way it does but some perform a bigger task. They define how the program looks and works.

3.1 Graphical User Interface

This part of the project was implemented in Java using two external libraries, RXT for the serial communication and the Swing libraries to visualize the sensor data.

3.1.1 SerialConn

This component takes care of the connection between the XBee and the computer. It can open and close a serial port on the computer. The data that arrives on this serial port is made available to the application. First, an instruction code is read. The instruction code is used to find the number of integers that have to be read. Those integers are the arguments for the instruction. When all arguments are read, the data is sent to the input parser which will extract the data and process it. All this is done in a procedure that is implemented as a state machine and called when a new byte becomes available. This has also been described in the technical document[6].

3

3.1.2

Input parser

The input parser is a singleton class to allow only one parser to process the data. One parser also results in one action that is performed when new data is available. The most important method of this class is the parse method. It takes an instruction code and a number of integer arguments as input. Every instruction was assigned a different action. Every call to the parse function contains an identification from the sensor that sent the value. Based on that, the correct method from the datastore instance is called to store the value in the right place.

3.1.3 Datastore

This is also a singleton class and the model in the Model-View-Controller design pattern[2] we used. This means that there is only one data store which keeps all the data of the system. This data is used by the Canvas to draw the GUI. Some values can be derived from other values. For example, if the number of rotations per minute is updated, the driven distance is also updated.

3.1.4 Canvas

This is one of the two main constituents that form the view part of the MVC pattern. It reads

the data from the datastore and draws it on the window. Every sensor is drawn in a separate

part of the window. The components displayed on the canvas make extensive use of the Swing libraries.

3.2

Robotcontroller

The second part of the project was created in XC and C. XC is used to access procedures and data types that are specific on the XMOS platform. The C programming language was used to be able to use pointers which are mainly used in the sensor data structure.

3.2.1 Sensor and SensorManager

The sensor struct and the sensormanager are always used together as sensors use pointers and

XC doesn’t support the usage of pointers. The sensormanager hides these pointers by providing

functions that don’t have pointers in their signature but use them internally. For example to read the value of a sensor, in XC a function is called with an index and a core number. In this function, the pointer to the sensor struct is looked up and the function that is contained in this sensor is called.

A sensor struct contains all data that must be known about that sensor such as how the sensor

must be read, how a value must be compared with the threshold. Sometimes the value must be

smaller than the threshold where in other cases the value must be bigger. The identification of

the sensor that is required by the computer to be able to store the data in the right place is also

in this sensor struct.

The sensormanager keeps a number of sensor structs in an array and provides functions that are syntactic sugar for retrieving and performing an operations on the sensors themselves.

4

3.2.2

Main

This is the core of the program, the main function is the most important part. Here the different threads are started that will control the robot such as reading the sensor values, transmitting and receiving data, controlling the motors and others.

4 Description of Code

This section contains a description of the other components. These are the less important parts in both programs yet they are necessary to give the applications their functionality.

4.1 Graphical User Interface

The following component’s make up the graphical user interface. Every components functionality briefly described here. In the code itself at the end of the document (section 5), more detailed comments are given alongside the code.

4.1.1 AboutDialog

This is the about dialog which shows information about the program. It has no real functionality in the program.

4.1.2 Message

The message class allows the program to show messages to the user. The advantage of using a separate class for this is that the programmer can decide how the messages should be displayed, they can be displayed in a popup box, in a separate window or on the window itself. There are two types of messages, regular messages and error messages.

4.1.3 PreferencesDialog

In the preferences dialog, the user can set the different threshold values. The port to which the XBee is connected on the computer can also be changed here.

4.1.4 RobotControllerApp

This class contains the main method of the application. It is the first class that will be loaded and it will initialize some values in the constants class. It also sets the application icon and other platform specific settings, especially on the Mac OSX platform.

4.1.5 RobotControllerView

This is the window that is the application, it creates an instance of the canvas class and adds it to the window which is the second part of the view component in the MVC pattern. It also creates and adds the menubar. If a key is pressed in the window, an action is triggered and that command is sent to the robot.

5

4.1.6

UpdateAbleSensor

This class is a utility class that combines an input box from the preferences dialog with the datastore procedure that corresponds to that input box. It keeps track of the threshold value before the dialog was shown. If the current value is different from the previous value, the new value is sent to the robot.

4.2

Robotcontroller

ADClib

This library is used to read the analog value that was converted to a 12 bit digital number by the analog to digital converter. There are 4 channels available on the hardware but the code also supports the 7 channel version of the ADC we used.

4.2.1 Initialization

This component initializes the data structures such as the sensor manager and the protocol array for the input parser.

4.2.2 InputParser

The input parser here is the counterpart of the input parser in the graphical user interface. All commands that are sent by the computer are parsed here and the appropriate action is called.

4.2.3 LightSensor, RangeSensor, RpmSensor and TemperatureSensor

The four sensor structs that are used in the program contain operations to read the sensor, an action that is called when the threshold is passed, a function to compare a value to the threshold

4.2.4 Motor

The commands they send

require precise timing. If this timing is incorrect, the motor could rotate backwards instead of forward.

This component contains the procedures that control the motors.

4.2.5 XBeelib

The XBee library takes care of sending and receiving data over the Zigbee network. It can send and receive byte and integer values.

4.2.6 xcWrapper

This library is a collection of utility functions that perform specific XC operations that C cannot perform. By hiding the XC-specific operations inside a function, C-code can also perform these operations. This is needed in some operations in a C file.

6

5

Code Listings

All code was documented in a style so that Doxygen can generate the documentation. This documentation can be found online for both the graphical user interface [3] and the robot control program [4].

5.1 Graphical User Interface

5.1.1

AboutDialog.java

1

package robotcontroller;

2

3

/∗∗

4

5

@file AboutDialog.java

6

7

This class creates and displays an about dialog.

8

9

@author Jasper Maes <jasper.maes@gmail.com>

10

11

/

12

public class AboutDialog extends javax.swing.JDialog {

13

14

/∗∗

15

Creates and shows a new AboutDialog.

16

17

@param parent The parent window of the dialog

18

/

19

public AboutDialog(java.awt.Frame parent) {

20

super(parent, true);

21

initComponents();

22

23

setVisible(true);

24

}

25

26

27

28

/∗∗ This method is called from within the constructor to

29

initialize the form.

30

WARNING: Do NOT modify this code. The content of this method is

31

always regenerated by the Form Editor.

32

/

33

@SuppressWarnings(”unchecked”)

34

// <editorfold defaultstate=”collapsed” desc=”Generated Code”>//GENBEGIN:initComponents

35

private void initComponents() {

36

37

jLabel1 = new javax.swing.JLabel();

38

jLabel2 = new javax.swing.JLabel();

39

40

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE ON CLOSE);

41

org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(robotcontroller.RobotControllerApp.class).getContext().g

7

42

setBackground(resourceMap.getColor(”Form.background”)); // NOI18N

43

setModal(true);

44

setName(”Form”); // NOI18N

45

setResizable(false);

46

47

jLabel1.setText(resourceMap.getString(”jLabel1.text”)); // NOI18N

48

jLabel1.setName(”jLabel1”); // NOI18N

49

50

jLabel2.setIcon(resourceMap.getIcon(”jLabel2.icon”)); // NOI18N

51

jLabel2.setText(resourceMap.getString(”jLabel2.text”)); // NOI18N

52

jLabel2.setName(”jLabel2”); // NOI18N

53

54

org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());

55

getContentPane().setLayout(layout);

56

layout.setHorizontalGroup(

57

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

58

.add(layout.createSequentialGroup()

59

.addContainerGap()

60

.add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED SIZE, org.jdesktop.layout.GroupLayout.DEFAULT SIZE, org.jdesktop.layout.GroupLayout.PREFERRED SIZE))

61

.add(jLabel2)

62

);

63

layout.setVerticalGroup(

64

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

65

.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()

66

.add(jLabel2)

67

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT SIZE, Short.MAX VALUE)

68

.add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED SIZE, org.jdesktop.layout.GroupLayout.DEFAULT SIZE, org.jdesktop.layout.GroupLayout.PREFERRED SIZE)

69

.addContainerGap())

70

);

71

72

pack();

73

}// </editorfold>//GENEND:initComponents

74

75

// Variables declaration do not modify//GENBEGIN:variables

76

private javax.swing.JLabel jLabel1;

77

private javax.swing.JLabel jLabel2;

78

// End of variables declaration//GENEND:variables

79

80

}

5.1.2

Canvas.java

1

package robotcontroller;

2

3

import java.awt.AlphaComposite;

4

import java.awt.Color;

5

import java.awt.Font;

6

import java.awt.Graphics;

8

7

import java.awt.Graphics2D;

8

import java.awt.Rectangle;

9

import java.awt.RenderingHints;

10

import java.awt.event.MouseEvent;

11

import javax.swing.JPanel;

12

import java.awt.Image;

13

import java.awt.Point;

14

import java.awt.event.MouseAdapter;

15

import java.awt.geom.AffineTransform;

16

import java.awt.image.BufferedImage;

17

18

/∗∗

19

20

@file canvas.java

21

22

This class contains methods that are used to draw the different sensor values on a JPanel object.

23

24

@author Jasper Maes <jasper.maes@gmail.com>

25

26

/

27

public class Canvas extends JPanel {

28

29

/∗∗

30

This Rectangle object contains the area where the connection icon is drawn.\n

31

It is also used to check if the user clicked this icon.

32

/

33

private static final Rectangle CONN RECT = new Rectangle(555, 350, Globals.connLostImage.getWidth(null), Globals.connLostImage.getHeight(null));

34

/∗∗ At this point, the speed information will be drawn. /

35

private static final Point SPEED POINT = new Point(60, 390);

36

/∗∗ At this point, the driven distance information will be drawn. /

37

private static final Point DISTANCE POINT = new Point(360, 390);

38

/∗∗

39

This Rectangle object contains the area where the warning icon is drawn.\n

40

It is also used to check if the user clicked this icon.

41

/

42

private static final Rectangle WARN RECT = new Rectangle(230, 320, Globals.warning.getWidth(null), Globals.warning.getHeight(null));

43

/∗∗ This object is used to make the images less visible. It sets the transparency to 85%. /

44

private static final AlphaComposite transp = AlphaComposite.getInstance(AlphaComposite.SRC OVER, 0.15f);

45

/∗∗ This object is used to make the images visible. It sets the transparency to 0%. /

46

private static final AlphaComposite notransp = AlphaComposite.getInstance(AlphaComposite.SRC OVER, 1.0f);

47

/∗∗

48

This variable is used to create the image of the distance sensor and the robot together.

49

This is used to make it possible to turn the whole as the robot rotates.

50

/

51

private BufferedImage buffer = new BufferedImage(Globals.distanceSensor.getWidth(), Globals.distanceSensor.getHeight(), BufferedImage.TYPE INT ARGB);

52

/∗∗ The graphics object that is used to draw on the buffer image. /

53

private Graphics2D bufferGraphics = buffer.createGraphics();

54

/∗∗ The image that is shown when the connection was lost. /

9

55

private Image lostImage = null;

56

/∗∗ An italic font used for drawing text. /

57

private static final Font itFont = new Font(”Serif”, Font.ITALIC, 20);

58

/∗∗ A font used to draw the numbers. /

59

private static final Font numFont = new Font(”Serif”, Font.PLAIN, 60);

60

/∗∗ This variable contains the instance of the DataStore. /

61

private static final DataStore data = DataStore.getInstance();

62

63

/∗∗

64

This class extends the MouseAdapter class to make the application react

65

when a mouse button is clicked. It is implemented as an private inner class

66

to hide it from the rest of the program.

67

/

68

private class canvasMouseListener extends MouseAdapter {

69

70

/∗∗

 

71

The procedure that is called when the a mouse button is clicked.

72

73

@param e A MouseEvent object containing information about the mouse click that occurred

74

75

/

76

@Override

 

77

public void mouseClicked(MouseEvent e) {

78

if (e.getButton() == MouseEvent.BUTTON1) {

79

if (CONN RECT.contains(e.getPoint())) {

80

if (SerialConn.isConnected()) {

81

SerialConn.close();

82

} else { // Open new connection

83

new SerialConn(Globals.prefs.get(Globals.pref Port, Globals.def Port));

84

}

85

86

}

87

}

88

}

89

}

90

91

/∗∗

92

Creates new canvas

 

93

94

@param parent A RobotControllerView window. The new canvas will be part of this window.

95

/

96

public Canvas(RobotControllerView parent) {

97

addMouseListener(new canvasMouseListener());

98

99

setSize(Globals.MIN WIDTH, Globals.MIN HEIGHT);

100

101

parent.getContentPane().setBackground(Color.BLACK);

102

103

setOpaque(false);

 

104

}

105

106

/∗∗

107

This method draws a given string at the given point using a graphics object.

10

108

109

@param s The string to be drawn

110

@param p The position of the string

111

@param g2 The graphics object that is used for drawing

112

/

113

private static void drawString(String s, Point p, Graphics2D g2) {

114

g2.drawString(s, p.x, p.y);

115

}

116

117

/∗∗

118

This method is used to draw the different sensors and their values on the canvas.

119

120

@param g A graphics object, used to paint with

121

/

122

@Override

123

public void paint(Graphics g) {

124

Graphics2D g2 = (Graphics2D) g;

125

super.paintComponent(g2);

126

127

g2.setRenderingHint(RenderingHints.KEY ANTIALIASING, RenderingHints.VALUE ANTIALIAS ON);

128

129

boolean connected = data.getConnectionStatus();

130

131

if (!connected) { // Set transparency of all following draw operations

132

g2.setComposite(transp);

133

}

134

135

// Draw the robot and the distance sensor value

136

bufferGraphics.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());

137

138

// Draw the robot image and distance sensor

139

bufferGraphics.drawImage(Globals.distanceSensor, 0, 0, this);

140

bufferGraphics.setColor(Color.BLACK);

141

int[] val = data.getDistanceSensor();

142

if (connected) {

143

bufferGraphics.fillRect(0, 0, 250, val[0] 27 + 11);

144

bufferGraphics.fillRect(250, 0, 500, val[1] 27 + 11);

145

}

146

147

bufferGraphics.drawImage(Globals.robot, 7, Globals.robot.getHeight() / 2 30, this);

148

149

AffineTransform at = new AffineTransform();

150

if (connected) {

151

at.rotate(data.getRotation(), 270, 210); // theta, x, y

152

}

153

at.translate(165, 30); //x, y

154

at.scale(.5, .5); // x, y

155

g2.drawImage(buffer, at, this);

156

157

// Draw the speed and driven distance

158

g2.setColor(Color.YELLOW);

159

g2.setFont(numFont);

11

160

if (connected) {

161

String s = new Integer(data.getSpeed()).toString();

162

for (int i = 0; i <= 3 s.length(); i++) {

163

s = ”0” + s;

164

}

165

166

drawString(s, SPEED POINT, g2);

167

168

s = new Integer(data.getDriven()).toString();

169

for (int i = 0; i <= 3 s.length(); i++) {

170

s = ”0” + s;

171

}

172

173

drawString(s, DISTANCE POINT, g2);

174

} else {

175

drawString(”000”, SPEED POINT, g2);

176

drawString(”000”, DISTANCE POINT, g2);

177

}

178

g2.setFont(itFont);

179

g2.drawString(Globals.SpeedString, SPEED POINT.x + 110, SPEED POINT.y);

180

g2.drawString(Globals.DistanceString, DISTANCE POINT.x 30, DISTANCE POINT.y);

181

182

// Lightsensor

183

at = new AffineTransform();

184

at.translate(560, 30);

185

at.scale(0.65, 0.65);

186

g2.setColor(Color.yellow);

187

if (connected) {

188

g2.fillRect(560, (int) (30 + (26 + data.getLightSensor() 70) 0.65), (int) (31 0.65), (int) ((DataStore.MAX LIGHT SENSOR data.getLightSensor()) 70 0.65));

189

}

190

g2.drawImage(Globals.lightSensor, at, this);

191

192

// Temperaturesensor

193

at = new AffineTransform();

194

at.translate(500, 45);

195

at.scale(0.55, 0.55);

196

g2.setColor(Color.red);

197

int height = (int) ((75 + data.getTemperatureSensor() 4.2) 0.55);

198

if (connected) {

199

g2.fillRect(505, 318 height, 35, height);

200

}

201

g2.drawImage(Globals.temperatureSensor, at, this);

202

203

// Connection status

204

Image connection = null;

205

if (connected) {

206

connection = Globals.connectedImage;

207

lostImage = null;

208

} else {

209

connection = Globals.connLostImage;

210

lostImage = Globals.lostMessage;

211

}

12

212

213

g2.drawImage(connection, (int) CONN RECT.getX(), (int) CONN RECT.getY(), this);

214

215

// draw all next things transparent

216

if ((data.getDistanceSensor()[0] != DataStore.MAX DISTANCE SENSOR) || (data.getDistanceSensor()[1] != DataStore.MAX DISTANCE SENSOR)) {

217

g2.setComposite(transp);

218

}

219

220

// Draw the warning symbol

221

g2.drawImage(Globals.warning, WARN RECT.x, WARN RECT.y, this);

222

223

g2.setComposite(notransp);

224

g2.drawImage(lostImage, 5, 120, this);

225

}

226

227

/∗∗

228

This method is called when new data is available in the DataStore

229

/

230

public synchronized void newDataAvailable() {

231

repaint();

232

}

233

}

5.1.3

DataStore.java

1

package robotcontroller;

2

3

/∗∗

4

5

@file DataStore.java

6

7

The data store implemented as a singleton class.\n

8

It contains the value of each sensor as it was sent to the computer.

9

10

@author Jasper Maes <jasper.maes@gmail.com>

11

12

/

13

public class DataStore {

14

15

/∗∗ The only instance of this singleton class /

16

private static final DataStore INSTANCE = new DataStore();

17

/∗∗ Connection status. True if connected /

18

private boolean connectionStatus = false;

19

/∗∗ Variable that stores the speed of the left motor. /

20

private int leftSpeed = 0;

21

/∗∗ Variable that stores the speed of the right motor. /

22

private int rightSpeed = 0;

23

/∗∗ Variable that stores whether the speed should be updated on the canvas or not. /

24

private static boolean speedEnabled = true;

25

/∗∗ The distance the left wheel has driven. /

26

private long leftDriven = 0;

27

/∗∗ The distance the right wheel has driven. /

28

private long rightDriven = 0;

13

29

/∗∗ The previous value of the distance the left wheel has driven. /

30 private double lastLeftDriven = 0;

31 /∗∗ The previous value of the distance the right wheel has driven. /

32 private double lastRightDriven = 0;

33 /∗∗ Variable that stores whether the driven distance should be updated on the canvas or not. /

34 private static boolean drivenEnabled = true;

35 /∗∗ The number of rotations per minute the left wheel makes. /

36 private int leftRpm = 0;

37 /∗∗ The number of rotations per minute the right wheel makes. /

38 private int rightRpm = 0;

39 /∗∗

40 The last time the left rpm value was updated.

41 /

42 private long lastleftrpmtime = System.currentTimeMillis() / 1000;

43 /∗∗

44 The last time the right rpm value was updated.

45 /

46 private long lastrightrpmtime = System.currentTimeMillis() / 1000;

47 /∗∗

48 The circumference of the wheels on the robot.

49 This value is used to calculate the driven distance and the speed.

50 /

51 private static double WHEEL CIRC = 0;

52 /∗∗

53 The distance between both wheels on the robot. This is used to

54 calculate how the robot turns.

55 /

56 private static double WHEEL DISTANCE = 0;

57 /∗∗

58 The number of radians the robot has rotated.

59 /

60 private double rotation = 0;

61 /∗∗

62 The boolean value that stores whether the rotation should be shown on the canvas.

63 /

64 private static boolean rotationEnabled = true;

65 /∗∗

66 The value of the left distance senor.\n

67 The value was optimized to be displayed on the canvas.

68 /

69 private byte leftDistanceSensor = MIN DISTANCE SENSOR;

70 /∗∗

71 The value of the right distance senor.\n

72 The value was optimized to be displayed on the canvas.

73 /

74 private byte rightDistanceSensor = MIN DISTANCE SENSOR;

75 /∗∗ The minimal value of the distance sensor on the canvas in number of blocks. /

76 public static final byte MIN DISTANCE SENSOR = 0;

77 /∗∗ The maximal value of the distance sensor on the canvas in number of blocks. /

78 public static final byte MAX DISTANCE SENSOR = 8;

79 /∗∗ The boolean value that stores whether the distance to objects should be shown on the canvas. /

80 private static boolean distanceSensorEnabled = true;

81 /∗∗ The value of the light sensor, optimized to be displayed on the canvas. /

14

82

private byte lightSensor = MAX LIGHT SENSOR;

83

/∗∗ The minimal value of the light sensor on the canvas in number of light bulbs. /

84

public static final byte MIN LIGHT SENSOR = 0;

85

/∗∗ The maximal value of the distance sensor on the canvas in number of light bulbs. /

86

public static final byte MAX LIGHT SENSOR = 6;

87

/∗∗ The boolean value that stores whether the value of the light sensor should be shown on the canvas. /

88

private static boolean lightEnabled = true;

89

/∗∗ The value of the temperature sensor. /

90

private byte temperatureSensor = MIN TEMPERATURE SENSOR;

91

/∗∗ The minimal value of the light sensor on the canvass. /

92

public static final byte MIN TEMPERATURE SENSOR = 0;

93

/∗∗ The maximal value of the distance sensor on the canvas. /

94

public static final byte MAX TEMPERATURE SENSOR = 100;

95

/∗∗ The boolean value that stores whether the value of the temperature sensor should be shown on the canvas. /

96

private static boolean temperatureEnabled = true;

97

98

/∗∗

99

The constructor of this class is private so that no new objects can be created.\n

100

In a singleton class, there should only be 1.\n

101

This function is called when the application is initialized to create the instance

102

that is used throughout the application.

103

/

104

public DataStore() {

105

double WHEEL DIAM = Globals.prefs.getInt(Globals.pref WheelDiam, Globals.def WheelDiam) / 1000;

106

WHEEL CIRC = Math.PI WHEEL DIAM;

107

WHEEL DISTANCE = Globals.prefs.getInt(Globals.pref WheelDist, Globals.def WheelDist) /

1000;

108

}

109

110

/∗∗

111

This function returns the only instance of this class. It can then be used to get

112

a sensor value or to update a value.

113

114

@return The instance of this class

115

/

116

public static DataStore getInstance() {

117

return INSTANCE;

118

}

119

120

/∗∗

121

Returns the connection status

122

123

@return True or false depending on the status of the connection

124

/

125

public boolean getConnectionStatus() {

126

return connectionStatus;

127

}

128

129

/∗∗

130

Updates the connection status.

15

131

132

@param conn A boolean indicating whether the connection is active or not.

133

/

134

public void setConnectionStatus(boolean conn) {

135

connectionStatus = conn;

136

}

137

138

/∗∗

139

Method to set the left rpm.\n

140

It also updates the current speed and rotation.

141

142

@param r The number of rotations per minute of the left motor

143

/

144

public void setLeftRpm(int r) {

145

updateDriven();

146

lastleftrpmtime = System.currentTimeMillis() / 1000;

147

leftRpm = r;

148

updateSpeed();

149

updateRotation();

150

}

151

152

/∗∗

153

Method to set the right rpm.\n

154

It also updates the current speed and rotation.

155

156

@param r The number of rotations per minute of the right motor

157

/

158

public void setRightRpm(int r) {

159

updateDriven();

160

lastrightrpmtime = System.currentTimeMillis() / 1000;

161

rightRpm = r;

162

updateSpeed();

163

updateRotation();

164

}

165

166

/∗∗

167

Method to set the rpm of both the left and right motor at the same time.\n

168