-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbotFunctions.mjs
More file actions
233 lines (208 loc) · 8.96 KB
/
botFunctions.mjs
File metadata and controls
233 lines (208 loc) · 8.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*==============================================================================
(C) Copyright 2017,2018,2019,2020,2022 John J Kauflin, All rights reserved.
-----------------------------------------------------------------------------
DESCRIPTION: NodeJS module to handle robot functions. Communicates with
the Arduino Mega, and accepts commands from user input
-----------------------------------------------------------------------------
Modification History
2017-12-31 JJK Loaded ConfigurableFirmata on the Arduino Mega.
LED functions working ok
2018-01-12 JJK Tested LED, Servo, and Motor successfully. Connecting
servo back on motorshield and using 4 AA pack shared with
motors
2018-01-15 JJK Creating functions to be called from the controller
2018-01-24 JJK Corrections after testing manual controls
2018-01-26 JJK Modified board initialization for running as a service
2018-01-27 JJK Modified to use PingFirmata to get the HC-SR04 ultrasonic
proximity sensor working
2018-02-10 JJK Implemented the general botEvent, checking for Board errors,
and sending an error event.
Working with proximity sensors
2018-12-01 JJK Updated to johnny-five 1.0.0
2018-12-21 JJK Getting the robot function working again
2018-12-22 JJK Adding animation to go along with speaking text
2018-12-26 JJK Got some speech animation working using LED strobe, and
servo animations for head and arm (turned off with and event
from the client saying the utterance was done speaking)
2019-01-30 JJK Modified the animate speech to calculate time from words
(like the JohnBot in Android did)
2019-02-10 JJK Added boardReady check before executing commands
2019-02-15 JJK Added logic for walkAbout - realized I needed a way to
execute multiple async loop commands in order, so implemented
an execution controller and a command request array
2019-02-16 JJK Added stop and turn around on close proximity
2019-03-29 JJK Moved the motor initialize to the top
2019-04-07 JJK Updated the rotate duration calculation
2019-04-10 JJK Adjustments to the rotate calculations (to get better)
Working on proximity slow and stop
2019-04-12 JJK Checking servo sweep and position functions (for improved
object awareness with the proximity sensor)
Adjusting proximity actions - got walk around working better
2019-06-23 JJK Getting servo sweep with proximity sensor working (now that
Amy has glued it together), and modified the walk around
to turn the right direction away from the proximity alert
2019-07-06 JJK Cleaning up command execution and state to give more
encapsulation and independance (so they can be more complex)
2019-07-07 JJK Did not work well trying to put everything through the
command queue, so I'm trying some more direct calls like
I was doing
2019-07-21 JJK Working better with direct calls. Added a backup for close
proximities. Working on checking the health of the proximity
sensor
2019-09-22 JJK Checking functions (updated to johnny-five 1.3.1)
2019-10-03 JJK Getting 2nd distance sensor working, and adding a piezo
speaker
2020-05-04 JJK Trying to get the JohnBot working on a full Pi rather than
a Pi Zero (to see if the sensors work better)
2020-05-09 JJK Re-checking distance sensors, cntrl-c, and all stop functions
Fixed bug in proximityAlert for 2 sensors
Added execution with forever and a reset option (for when
it freezes up). Working on the speaking animation
2020-05-12 JJK Implementing _proximitySensor handler
Working on moving, walking, and rotate
2020-05-17 JJK Turning off the head and arm servos for now (power problems)
Working on moving logical
2020-05-30 JJK Working on distance sensor accuracy by adding smoothing
2021-10-09 JJK Re-looking at the JohnBot - turning off the connection to
chatbot and reworking the loops for sensors
2022-05-01 JJK Ok, back to JohnBot - newest OS (Buster) and starting to
re-check functions
2023-11-07 JJK Getting bot functions working under new OS (Bookworm) in
an ESM module, and trying new infrared proximity sensor
=============================================================================*/
import johnnyFivePkg from 'johnny-five' // Library to control the Arduino board
import {log} from './util.mjs' // My utility functions
const {Board,Led,Leds,Relays,Proximity} = johnnyFivePkg
var board = null
var relays = null
// Constants for pin numbers and commands
const LEFT_EYE = 45;
const RIGHT_EYE = 44;
var eyes;
var leftEyeLed;
var rightEyeLed;
var eyesOn = false;
var speaking = false;
// Create Johnny-Five board object
// When running Johnny-Five programs as a sub-process (eg. init.d, or npm scripts),
// be sure to shut the REPL off!
try {
log("===== Starting board initialization =====")
board = new Board({
repl: false,
debug: false
// timeout: 12000
})
} catch (err) {
log('Error in main initialization, err = ' + err)
console.error(err.stack)
}
board.on("error", function (err) {
log("*** Error in Board ***")
console.error(err.stack)
})
//-------------------------------------------------------------------------------------------------------
// When the board is ready, create and intialize global component objects (to be used by functions)
//-------------------------------------------------------------------------------------------------------
board.on("ready", () => {
log("*** board ready ***")
leftEyeLed = new Led(LEFT_EYE);
rightEyeLed = new Led(RIGHT_EYE);
eyes = new Leds([leftEyeLed, rightEyeLed]);
//eyes.on();
//eyes.off();
//eyes.strobe(150);
/*
new five.Proximity({
controller: "GP2Y0A21YK",
pin: "A8"
});
*/
// Start the function to toggle air ventilation ON and OFF
/*
log("Starting Air toggle interval")
setTimeout(toggleAir, 5000)
// Start sending metrics 10 seconds after starting (so things are calm)
setTimeout(logMetric, 10000)
*/
// Handle a termination signal
process.on('SIGINT', function () {
log('>>> in bot - on SIGINT - allStop')
allStop()
})
log("End of board.on (initialize) event")
})
export function allStop() {
log(">>>>> bot - ALL STOP");
// Stop all motion
//_stopWalking();
// Stop all components
_doneSpeaking();
//walkAboutMode = false;
//walkMode = false;
// Clear the function calls
/*
clearTimeout(_executeCommands);
clearTimeout(_stopWalking);
clearTimeout(_startWalking);
clearTimeout(_rotate);
clearTimeout(_walk);
clearTimeout(_walkAbout);
*/
}
function _getRandomInt(min, max) {
// Floor - rounded down to the nearest integer
return Math.floor(Math.random() * (max - min)) + min;
}
export function animateSpeech(textToSpeak) {
// Cancel any running animations before starting a new one
_doneSpeaking();
// Calculate a milliseconds time from the textToSpeak and set a _doneSpeaking function call
// (just calculate using the word count for now)
var wordList = textToSpeak.split(" ");
//for (var i = 0; i < wordList.length; i++) {
//wordList[i]
//}
var speakingDuration = wordList.length * 309;
setTimeout(_doneSpeaking, speakingDuration);
speaking = true;
// Start strobing the eye leds
eyes.strobe(150);
try {
/*
speechAnimation.enqueue({
duration: 2000,
cuePoints: [0, 0.25, 0.5, 0.75, 1.0],
keyFrames:
[
[null, { degrees: 50 }, { degrees: 120 }, { degrees: 55 }, { degrees: 90 }],
[null, { degrees: 60 }, { degrees: 105 }, { degrees: 75 }, { degrees: 90 }]
],
loop: true,
onstop: function () {
//console.log("Animation stopped");
//Use onstop functions when your looping animation is halted to return a bot's animated limbs to their home positions.
//Nearly always use null as the first value in an animation segment. It allows the segment to be started from a variety of positions.
// Center? seems to mess things up
//headAndArm.home();
},
oncomplete: function () {
//console.log("Animation complete");
}
});
*/
}
catch (error) {
console.error(">>> speechAnimation error = " + error);
}
}
function _doneSpeaking() {
//log("doneSpeaking");
if (speaking) {
//log("clearTimeout for _doneSpeaking");
clearTimeout(_doneSpeaking);
//speechAnimation.stop();
eyes.stop().off();
speaking = false;
}
}