Updated readme and fixed typos

This commit is contained in:
alastaira
2023-09-18 19:58:28 +01:00
parent d731769335
commit ee3e6e625c
6 changed files with 46 additions and 67 deletions

View File

@@ -84,7 +84,7 @@ void FaceBehavior::GoToEmotion(eEmotions emotion) {
case eEmotions::Annoyed: _face.Expression.GoTo_Annoyed(); break;
case eEmotions::Surprised: _face.Expression.GoTo_Surprised(); break;
case eEmotions::Skeptic: _face.Expression.GoTo_Skeptic(); break;
case eEmotions::Fustrated: _face.Expression.GoTo_Fustrated(); break;
case eEmotions::Frustrated: _face.Expression.GoTo_Frustrated(); break;
case eEmotions::Unimpressed: _face.Expression.GoTo_Unimpressed(); break;
case eEmotions::Sleepy: _face.Expression.GoTo_Sleepy(); break;
case eEmotions::Suspicious: _face.Expression.GoTo_Suspicious(); break;

View File

@@ -30,7 +30,7 @@ enum eEmotions {
Annoyed,
Surprised,
Skeptic,
Fustrated,
Frustrated,
Unimpressed,
Sleepy,
Suspicious,

View File

@@ -116,7 +116,7 @@ void FaceExpression::GoTo_Skeptic()
_face.LeftEye.TransitionTo(Preset_Skeptic_Alt);
}
void FaceExpression::GoTo_Fustrated()
void FaceExpression::GoTo_Frustrated()
{
ClearVariations();
_face.RightEye.TransitionTo(Preset_Fustrated);

View File

@@ -40,7 +40,7 @@ class FaceExpression {
void GoTo_Annoyed();
void GoTo_Surprised();
void GoTo_Skeptic();
void GoTo_Fustrated();
void GoTo_Frustrated();
void GoTo_Unimpressed();
void GoTo_Sleepy();
void GoTo_Suspicious();

View File

@@ -6,10 +6,39 @@ Inspired by the expressive eye animations of the Anki "Cozmo" robot, this Arduin
<img src="https://github.com/playfultechnology/esp32-eyes/blob/main/doc/anki-cozmo-faces-3-1024x576.jpg" />
Unlike some libraries which require a set of bitmap images for each frame of animation, this library draws each frame dynamically from a programmatic set of parameters.
Unlike some libraries which display a set of pre-rendered bitmap images for each frame of animation, this library draws each frame dynamically from a programmatic set of parameters.
Heavily based on <a href="https://github.com/luisllamasbinaburo/ESP32_Faces/">this library</a>, although with significant adjustments:
- OLED (using <a href="https://github.com/olikraus/u8g2">u8g2</a>) rather than TFT (based on <a href="https://github.com/Bodmer/TFT_eSPI">eSPI_TFT</a>)
- Horizontal rather than vertical alignment
- Mirrored left/right eye animations
- Automatic or manual blink and look direction
## Component Structure
- *Face* is the core object, consisting of left and right eye components, behaviour, expression, a look assistant, and a blink assistant. The outputs of these components are chained together to create the display on each frame:
- The Face *Behaviour* contains an array of weighted _Emotions_. There are currently 18 emotions, as defined in the enum in FaceEmotions.hpp.
Each emotion can have an individual weight assigned to it, as follows:
```
face->Behavior.SetEmotion(eEmotions::Glee, 1.0);
face->Behavior.SetEmotion(eEmotions::Anger, 0.5);
```
If ```face->RandomBehavior = true;``` (which is the default), then Face will use a roulette-wheel selection to randomly assign a new emotion based on their relative weights.
The frequency with which the current emotion is re-evaluated (although this does not always result in a change) is determined by the value passed to ```face->Behaviour.Timer.SetIntervalMillis();```
(If no weights have been assigned to any emotion, the face will default to "normal" emotion).
Note that emotions are not blended together - the "weight" assigned to them determines the chances with which any emotion will be selected to be the next emotion (currentEmotion)
- *Expression* is a wrapper that handles transitions of each eye to the currently selected emotion.
- The Blink assistant handles blinking. If ```face->RandomBlink = true;``` (the default), the eyes will automatically blink, with a frequency determined by the value passed to ```face->Blink.Timer.SetIntervalMillis();```
The eyes may be blinked manually by calling ```face->DoBlink();```
- The Look assistant handles the global position of the eyes around the screen. If ```face->RandomLook = true;``` (the default), the eyes will randomly move around the screen, with a frequency determined by the value passed to ```face->Look.Timer.SetIntervalMillis();```
The eyes may be set to look at any position by calling ```face->Look.LookAt(x, y);``` (where x and y range from -1.0 - 1.0)
- Each eye is responsible for managing their own drawing operations to the display (in EyeDrawer.cpp)

View File

@@ -1,14 +1,8 @@
/***************************************************
Copyright (c) 2020 Luis Llamas
(www.luisllamas.es)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses
****************************************************/
* ESP32-Eyes, Copyright (c) 2023 Alastair Aitchison, Playful Technology
* Based on previous work by Luis Llamas (www.luisllamas.es)
*
****************************************************/
// INCLUDES
// Built-in Arduino I2C library
@@ -17,36 +11,18 @@ You should have received a copy of the GNU Affero General Public License along w
#include "Face.h"
// CONSTANTS
const byte joystickPins[] = {26, 25};
const byte blinkPin = 16;
// GLOBALS
Face *face;
String emotionName[] = {
"Normal",
"Angry",
"Glee",
"Happy",
"Sad",
"Worried",
"Focused",
"Annoyed",
"Surprised",
"Skeptic",
"Frustrated",
"Unimpressed",
"Sleepy",
"Suspicious",
"Squint",
"Furious",
"Scared",
"Awe"
};
void setup(void) {
// Create a serial connection
Serial.begin(115200);
Serial.println(__FILE__ __DATE__);
// Configure input pins
pinMode(blinkPin, INPUT_PULLUP);
// Create a new face
@@ -58,18 +34,16 @@ void setup(void) {
face->Behavior.SetEmotion(eEmotions::Normal, 1.0);
//face->Behavior.SetEmotion(eEmotions::Angry, 1.0);
//face->Behavior.SetEmotion(eEmotions::Sad, 1.0);
// Automatically select a random behaviour (based on the weight assigned to each emotion)
// Automatically switch between possible allowed behaviours (selecting new behaviour randomly based on the weight assigned to each emotion)
face->RandomBehavior = true;
// Automatically blink
face->RandomBlink = true;
// Set blink rate
face->Blink.Timer.SetIntervalMillis(4000);
//face->Blink.Timer.Stop();
// Automatically choose a new random direction to look
face->RandomLook = true;
face->RandomLook = false;
}
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
@@ -87,7 +61,8 @@ float mapFloat(float x, float in_min, float in_max, float out_min, float out_max
void loop(){
static int lastMoveTime;
// To avoid making eyes too twitchy (and to allow time for previous animation to end), we only recalculate new position every 500ms
// To avoid making eyes too twitchy (and to allow time for previous move animation to end),
// only recalculate new position every 500ms
if(millis() - lastMoveTime > 500) {
int yRaw = analogRead(25);
int xRaw = analogRead(26);
@@ -96,11 +71,11 @@ void loop(){
face->Look.LookAt(x, y);
lastMoveTime = millis();
}
// Blink when joystick pressed in
if(!digitalRead(blinkPin)){
face->DoBlink();
}
/*
// Use this code to set a particular emotion from a button
int32_t potValue = analogRead(15);
@@ -108,31 +83,6 @@ void loop(){
face->Behavior.SetEmotion(eEmotions::Angry, anger);
*/
/*
// Use this code to cycle automatically through all emotions
static uint32_t counter = millis();
static uint8_t emotionno = 0;
static uint8_t changeEmotionFlag = 0;
static uint8_t n = 0;
if(millis() - counter > 6000) {
counter = millis();
emotionno = n++;
if(n >= EMOTIONS_COUNT) n = 0;
changeEmotionFlag = 1;
}
if(changeEmotionFlag) {
// Clear any previously assigned weights
face->Behavior.Clear();
// Assign weight of 1.0 to the next emotion in the list
face->Behavior.SetEmotion((eEmotions)emotionno, 1.0);
// Print the new emotion to the serial monitor
Serial.println(emotionName[emotionno]);
// Reset the flag
changeEmotionFlag = 0;
}
*/
// Update the face!
face->Update();
//delay(10);
}