Arduino Forum

General Category => General Discussion => Topic started by: goodinventor on Jan 24, 2016, 06:18 pm

Title: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Jan 24, 2016, 06:18 pm
Hello everyone,

I am working on a robotics project, and I thought I should share it with you now that I have gotten some of the hardware and software working. I have named it the "Deep Think Project". It is a research project focused on artificial intelligence and humanoid robotics. Right now I am using the Meccanoid G15, the 86Duino One, and a 9-Volt battery with snap connector. So far I have gotten the servos working. Below is the code.

Code: [Select]

//
// Deep Think 0.0.0.1
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Control the output of the LED eyes with the 86Duino.
// 2. Control the 4 Smart Servos with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
//

#include "MeccaBrain.h"

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

void setup()
{
}

void loop()
{
  // sets LED and servo color to red
  LEDEye.setLEDColor(7, 0, 0, 4);
  LEDEye.communicate();
  LeftArmDaisyChain.setServoColor(0, 0xF1);
  LeftArmDaisyChain.communicate();
  RightArmDaisyChain.setServoColor(0, 0xF1);
  RightArmDaisyChain.communicate();
 
  // moves arms up
  LeftArmDaisyChain.setServoPosition(0, 255);
  LeftArmDaisyChain.communicate();
  RightArmDaisyChain.setServoPosition(0, 0);
  RightArmDaisyChain.communicate();
 
  // wait 1 second
  delay(1000);
 
  // moves arms down
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
 
  // wait 3 more seconds until next iteration
  delay(3000);
}


This is a very simple demo starting program, and so does little except insure that the servos, the official Arduino library for the Meccanoid G15, the LED eyes, and my method for writing to the Smart Modules are all functioning properly. I have tweaked the code a few times recently when the code didn't work as I intended, but now I have tested it and the code works. Next I plan on creating some functions for doing different movements with the servos and D/C motors. Any recommendations on new functionality and improvement will be greatly appreciated. I expect this project will take a very long time to complete, if I ever finish it, and I am willing to press on with this project for years. I have researched some possible deep learning algorithms for implementing in this robot, and the one I think will be best for this project is the LAMSTAR algorithm. Size of the program plus bootloader so far is 156KB. I expect that in the near future I will need to upgrade the brain for the robot in order to run the learning algorithm and machine vision.

Thank you all for your support,
goodinventor
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 07, 2016, 09:05 pm
Hello everyone,

I have been working on some basic functions for movement, and although the code compiles fine, it doesn't do what I want. The robot takes a long time to initialize, and then it just raises it's left arm. I don't know what's wrong with my code even after hours of looking at it, so I am posting it here. Here is my code.

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  LeftArmDaisyChain.setServoPosition(0, 127);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  RightArmDaisyChain.setServoPosition(0, 127);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  delay(3000);
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

void setup()
{
  // set up DC motors
  pinMode(
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  delay(2000);
  PutDownLeftHand();
  PutDownRightHand();
  delay(2000);
 
  WaveWithLeftArm();
  delay(2000);
  WaveWithRightArm();
  delay(2000);
 
  TurnLeft();
  delay(1000);
  TurnRight();
  delay(1000);
 
  MoveForward();
  delay(2000);
 
  ReceiveWithLeftHand();
  delay(2000);
  PutDownLeftHand();
  delay(2000);
 
  ReceiveWithRightHand();
  delay(2000);
  PutDownRightHand();
  delay(2000);
}


Thank you,
goodinventor
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: el_supremo on Feb 07, 2016, 09:35 pm
Quote
although the code compiles fine
No it doesn't.
Code: [Select]
 // set up DC motors
  pinMode(


Pete
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 07, 2016, 10:26 pm
Hmmm...my code got changed since I last compiled and uploaded it. I should have checked the code first before posting. I'll fix that right away.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 07, 2016, 10:31 pm
Here is the fixed code. Can you find any other issues?

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  LeftArmDaisyChain.setServoPosition(0, 127);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  RightArmDaisyChain.setServoPosition(0, 127);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  delay(3000);
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  delay(2000);
  PutDownLeftHand();
  PutDownRightHand();
  delay(2000);
 
  WaveWithLeftArm();
  delay(2000);
  WaveWithRightArm();
  delay(2000);
 
  TurnLeft();
  delay(1000);
  TurnRight();
  delay(1000);
 
  MoveForward();
  delay(2000);
 
  ReceiveWithLeftHand();
  delay(2000);
  PutDownLeftHand();
  delay(2000);
 
  ReceiveWithRightHand();
  delay(2000);
  PutDownRightHand();
  delay(2000);
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: el_supremo on Feb 08, 2016, 02:44 am
Quote
9-Volt battery
That isn't going to power servos and all the other stuff.

I've never used any of the hardware you're using and I don't have the library so I can't be any further help with this.

Pete
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 08, 2016, 12:55 pm
OK. I have tested it though, and the 9-volt battery seems to be able to at least power the servos. It's the DC motors which don't move at all. I should probably get a larger capacity battery at 5V to power the board through the USB client port. Perhaps this program will now work already since I finished the pinMode() statements for the DC motor pins. That may have been what was causing the program to act weird.

By the way, here is the library that I have been using. http://www.meccano.com/meccanoid-opensource (http://www.meccano.com/meccanoid-opensource)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: RayLivingston on Feb 08, 2016, 04:41 pm
You're off to a very bad start with your liberal use of delay().  You will very quickly reach the point where your program becomes unresponsive because it's spending most of its time spinning its wheels in delays.  You REALLY need to learn how to write non-blocking code....

Regards,
Ray L.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 08, 2016, 11:44 pm
Here is the fixed code. Can you find any other issues?

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  LeftArmDaisyChain.setServoPosition(0, 127);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down
  RightArmDaisyChain.setServoPosition(0, 127);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // up again
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  delay(500);
 
  // down all the way
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  delay(3000);
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  delay(3000);
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  delay(2000);
  PutDownLeftHand();
  PutDownRightHand();
  delay(2000);
 
  WaveWithLeftArm();
  delay(2000);
  WaveWithRightArm();
  delay(2000);
 
  TurnLeft();
  delay(1000);
  TurnRight();
  delay(1000);
 
  MoveForward();
  delay(2000);
 
  ReceiveWithLeftHand();
  delay(2000);
  PutDownLeftHand();
  delay(2000);
 
  ReceiveWithRightHand();
  delay(2000);
  PutDownRightHand();
  delay(2000);
}

That code is nothing like good. Your robot should be running everything all the time and be able to react to changing conditions immediately, not a chain of delays later.

No biggie. You've not been introduced to microcontrollers and event-driven code before.
This tutorial will teach How to do multiple things at once ... like cook bacon and eggs.

 http://www.gammon.com.au/blink
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 09, 2016, 01:44 am
I was planning on implementing this but at the time I was just trying to test the servos and DC motors. Once I got that up and running I was going to use a proper timer for speeding things up. It would also be a good idea to optimize the poorly managed Meccanoid library. I can tell they didn't spend much time writing it. Right now my program doesn't even come close to doing what I want. It is just a basic test of the Servo and DC motor functionality to make sure my hardware setup is OK.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 09, 2016, 02:18 am
It's best to test the hardware pieces each in its own sketch

Learn to do this event-driven (time is one kind of event) code approach and you won't need any timer library.

Run all your inputs, outputs and processes as separate tasks in loop(). It's easier to debug each one alone than all together.

Learn finite state machines to control all that very simply.

Learn these things and then look at your robot with new eyes.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 09, 2016, 03:11 am
Currently my subsystems that need to be tested are these.

1. Servos (4 in 2 daisy chains)(arms)
2. D/C motors (feet)
3. Obstacle Detection (using ultrasonic sensor)(eyes)
4. LED eyes (decorative part of the eyes)

Over time I will add and change the subsystems.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 09, 2016, 04:03 am
Currently my subsystems that need to be tested are these.

1. Servos (4 in 2 daisy chains)(arms)
2. D/C motors (feet)
3. Obstacle Detection (using ultrasonic sensor)(eyes)
4. LED eyes (decorative part of the eyes)

Over time I will add and change the subsystems.
Every one of those products has a library and example code doesn't it? Try that first.

The library source code should tell you how it gets the hardware to work. If you want more, there's the datasheet for the electronics parts and tons of help online.

Really though, learn the simple lesson of many-things-at-once (and BlinkWithoutDelay) before forming your vision of the robot.

You might want to play around with parallel processing and bus systems while you're at it.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: darkbluebit on Feb 09, 2016, 12:03 pm
OK. I have tested it though, and the 9-volt battery seems to be able to at least power the servos. It's the DC motors which don't move at all.
You could use an H-Bridge motor controller to spin DC motors with a separate power source. You can check my example here:
http://darkbluebit.com/arduino-robot-motor-control/ (http://darkbluebit.com/arduino-robot-motor-control/)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 09, 2016, 01:00 pm
I already learned how to blink an LED without using delay(). Once I implement it, I can then work on finding a fast interface for connecting the servos. I think the UARTs will do for this job. I am not sure why you mentioned learning parallel processing, since the Arduino can't multi process anyways. Or maybe you were referring to something else?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 09, 2016, 01:34 pm
I am not sure why you mentioned learning parallel processing
Because at some point, you'll want to spread the control across several processors?

Note: parallel processing is not necessarily multiprocessing.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 09, 2016, 02:44 pm
Yes, I know. It can be used to describe dividing the load across multiple cores or multiple processors.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 09, 2016, 03:03 pm
For parallel processing I think it is more efficient to just get a multi-core single board computer rather than multiple Arduinos. It takes up less space too. Of course, I may want to use two anyways: one for motor control and the other for the sensors and the machine learning. I can use my 86Duino One for driving the servos and D/C motors and some other SBC for the other tasks. If the other SBC has multiple cores I can use the <thread> library in C++ to make use of the extra cores. If the project gets this complex I might consider using a small OS to manage all the resources, such as a distribution of embedded Linux.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 09, 2016, 09:48 pm
I already learned how to blink an LED without using delay(). Once I implement it, I can then work on finding a fast interface for connecting the servos. I think the UARTs will do for this job. I am not sure why you mentioned learning parallel processing, since the Arduino can't multi process anyways. Or maybe you were referring to something else?
Just trying to save you a LOT of time and effort.

http://www.gammon.com.au/blink

Here is the lesson at the address above, with code development and all the whys
Quote
This question comes up practically every day on the Arduino forum - "how do I blink two LEDs at different rates?" or "how do I turn on and off two motors at different times?".

One of the problems is that beginners look at the "blink" tutorial program, which is:


void setup()
  {               
  pinMode(13, OUTPUT);     
  }

void loop()
  {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
  }



Now this works fine, to blink one LED. But to blink two LEDs you run into problems. It's OK if you want to blink them both at once:


void setup()
  {               
  pinMode(12, OUTPUT);     
  pinMode(13, OUTPUT);     
  }

void loop()
  {
  digitalWrite(12, HIGH);   // set the first LED on
  digitalWrite(13, HIGH);   // set the second LED on
  delay(1000);              // wait for a second

  digitalWrite(12, LOW);    // set the first LED off
  digitalWrite(13, LOW);    // set the second LED off
  delay(1000);              // wait for a second
  }



Or, if you want to do one after the other:



void setup()
  {               
  pinMode(12, OUTPUT);     
  pinMode(13, OUTPUT);     
  }

void loop()
  {
  digitalWrite(12, HIGH);   // set the first LED on
  delay(1000);              // wait for a second
  digitalWrite(12, LOW);    // set the first LED off
  delay(1000);              // wait for a second

  digitalWrite(13, HIGH);   // set the second LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the second LED off
  delay(1000);              // wait for a second 
  }



But what if you want to blink the two LEDs at different rates? Like, once a second for LED 1 and twice a second for LED 2?

This is where the delay function doesn't really help.

Let's look at an analogy. Say you want to cook breakfast. You need to cook:


    Coffee - takes 1 minute
    Bacon - takes 2 minutes
    Eggs - takes 3 minutes




Now a seasoned cook would NOT do this:


    Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.
    Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.
    Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.



The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).

In computer terminology this is blocking. That is, you don't do anything else until the one task at hand is over.

What you are likely to do is this:


    Start frying eggs. Look at watch and note the time.
    Glance at watch from time to time. When one minute is up then ...
    Start cooking bacon. Look at watch and note the time.
    Glance at watch from time to time. When another minute is up then ...
    Put coffee on. Look at watch and note the time.
    When 3 minutes are up, everything is cooked. Serve it all up.



In computer terminology this is non-blocking. That is, keep doing other things while you wait for time to be up.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 09, 2016, 10:24 pm
For parallel processing I think it is more efficient to just get a multi-core single board computer rather than multiple Arduinos. It takes up less space too. Of course, I may want to use two anyways: one for motor control and the other for the sensors and the machine learning. I can use my 86Duino One for driving the servos and D/C motors and some other SBC for the other tasks. If the other SBC has multiple cores I can use the <thread> library in C++ to make use of the extra cores. If the project gets this complex I might consider using a small OS to manage all the resources, such as a distribution of embedded Linux.
How many MCU's you think are in a Mercedes? By 2000 there were about 500.

Have you seen Arduino Micro or any Teensy board?

One reason to parallel process is to make modular systems that you can plug elements in to. It could be inherently expandable.

Another reason is that you can split event-driven code between processors, adding a cpu while sharing load.

You can run AVR chips stand-alone on breadboard or other like protoboard (solder sockets) as many in a row as you like, connect them all to SPI bus as master + slaves. 328P DIP chip costs me $2.20.

I've seen two people jump to Mega2560 from Uno when UNO + 328P would have done for much less.

This address has everything on making breadboard standalone AVR's featuring the 328P and the 1284P.
http://www.gammon.com.au/breadboard

The "Mighty" 1284P has 16K RAM, 4K EEPROM, 128K flash, 2 serial, >30 I/O pins.. ports with 8 pins open.

Look up the MIT High/Low Tech site for ATtiny programming. Those have 8 pins, 6 can be I/O and note that while RAM is minimal they still have their own cpu, their own 'attention' to be applied to some task.

Besides that, how do you have a "Deep Think" without parallel processing?
 
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Robin2 on Feb 09, 2016, 11:37 pm
I already learned how to blink an LED without using delay().
BWoD is like second week Recorder.

Artificial Intelligence is the New York Philharmmonic (or Jimi Hendrix, depending on taste).

...R
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 10, 2016, 12:55 am
Wiring up a whole bunch of AVR MCUs is useful if I want to control a lot of I/O pins very quickly (motor control), but for my deep learning and machine vision it would be cheaper and a more efficient use of space if I just get an SBC or even use a GPU. Also, programming the necessary number of small MCUs to do this is incredibly tedious and difficult to manage. I do think it is a good idea though the next time I need to write to a huge amount of I/O pins. The ATmega328P only has 16 DMIPS of processing power, whereas a Raspberry Pi 2 has nearly 7000 DMIPS! It would take a great many AVR chips to match that kind of processing power, plus it would require much more power due to so many separate chips. An alternative is for me to create a smaller cluster of much more powerful processors, such as a group of low-power ARM Cortex-A Series chips for the machine learning and vision and AVRs or ARM Cortex M Series processors for motor and basic I/O control (including gyroscopes, accelerometers, force sensors, you name it).
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 10, 2016, 03:04 am
They are right for automation but they can also be used to process stream data and serve as neural net nodes.

If I want a lot of pins, I'll use shift registers.

If you code right, 16 MIPS is plenty. Modular design just makes the whole process easier.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 10, 2016, 08:30 am
Quote
Also, programming the necessary number of small MCUs to do this is incredibly tedious and difficult to manage
Only if you use the wrong tools and languages.

Quote
The ATmega328P only has 16 DMIPS of processing power
Even fewer available, if you continue to use delay ()  :D

Code: [Select]
whereas a Raspberry Pi 2 has nearly 7000 DMIPS!
But very poor I/O drive capabilities, and is a bugger to program for real-time performance

Horses for courses.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 10, 2016, 12:20 pm
I am not saying that I want to use something like a Raspberry Pi for direct motor control. I am saying that I think it would be better to just use my 86Duino One (an Arduino compatible board with a lot of I/O pins) for controlling the motors and the basic sensors and use a more powerful SBC for the deep learning and vision.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 10, 2016, 04:30 pm
And parallel processing techniques make coordinating all the smart parts far easier than having one big program trying to do everything. Do you know how much of your own senses and muscle control is decentralized? Or in vital organs?


Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 10, 2016, 07:49 pm
Yes, I know. All the parts of the body are made up of tiny units functional units. I have one program now because the code has not gotten big enough to justify multiple programs and controllers. I can implement parallel processing also just by getting a motor controller (or more, depending on how big this gets), and a multi-core controller for other functions (more as the system gets more complex), such as the Parallella-16 Micro-Server. The main problem with just using a bunch of small MCUs is that to match the performance of an SBC they take up a lot more space. Secondly, they consume more power in a large array of chips.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 04:36 pm
Here is the new code. I got rid of delay() in my main program. In doing so I trimmed 36 bytes out of my program.  :) However, I feel that using goto is not the most efficient way. The problem is, I can't think of a better way at the moment. Perhaps you can give me further suggestions? In the meantime, I need to also get rid of delay() in the MeccaBrain library and use a faster communication protocol. Then I can think about parallel processing for some of the harder tasks. Thank you all!

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

// timer variables
unsigned long TimeNeeded;
unsigned long LastTimeUpdate = millis();

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;
 
  WLAT1:
  if (Time() == 1)
  {
    goto WLAT2;
  }
  else
  {
    goto WLAT1;
  }
 
  // down
  WLAT2:
  LeftArmDaisyChain.setServoPosition(0, 127);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  WLAT3:
  if (Time() == 1)
  {
    goto WLAT4;
  }
  else
  {
    goto WLAT3;
  }
 
  // up again
  WLAT4:
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  WLAT5:
  if (Time() == 1)
  {
    goto WLAT6;
  }
  else
  {
    goto WLAT5;
  }
 
  // down all the way
  WLAT6:
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;
 
  WRAT1:
  if (Time() == 1)
  {
    goto WRAT2;
  }
  else
  {
    goto WRAT1;
  }
 
  // down
  WRAT2:
  RightArmDaisyChain.setServoPosition(0, 127);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  WRAT3:
  if (Time() == 1)
  {
    goto WRAT4;
  }
  else
  {
    goto WRAT3;
  }
 
  // up again
  WRAT4:
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  WRAT5:
  if (Time() == 1)
  {
    goto WRAT6;
  }
  else
  {
    goto WRAT5;
  }
 
  // down all the way
  WRAT6:
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;
 
  TLT1:
  if (Time() == 1)
  {
    // continue...
  }
  else
  {
    goto TLT1;
  }
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  TimeNeeded = 3000;
 
  TRT1:
  if (Time() == 1)
  {
    // continue...
  }
  else
  {
    goto TRT1;
  }
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;
 
  MFT1:
  if (Time() == 1)
  {
    // continue...
  }
  else
  {
    goto MFT1;
  }
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

// time without delay()
int Time()
{
  unsigned long Interval = TimeNeeded;
  unsigned long CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  T1a:
  RaiseLeftHand();
  RaiseRightHand();
  TimeNeeded = 2000;
 
  T1b:
  if (Time() == 1)
  {
    // time is up; continue
    goto T2a;
  }
  else
  {
    // go back and repeat check
    goto T1b;
  }
 
  T2a:
  PutDownLeftHand();
  PutDownRightHand();
 
  T2b:
  if (Time() == 1)
  {
    goto T3a;
  }
  else
  {
    goto T2b;
  }
 
  T3a:
  WaveWithLeftArm();
 
  T3b:
  if (Time() == 1)
  {
    goto T4a;
  }
  else
  {
    goto T3b;
  }
 
  T4a:
  WaveWithRightArm();
 
  T4b:
  if (Time() == 1)
  {
    goto T5a;
  }
  else
  {
    goto T4b;
  }
 
  T5a:
  TurnLeft();
  TimeNeeded = 1000;
 
  T5b:
  if (Time() == 1)
  {
    goto T6a;
  }
  else
  {
    goto T5b;
  }
 
  T6a:
  TurnRight();
 
  T6b:
  if (Time() == 1)
  {
    goto T7a;
  }
  else
  {
    goto T6b;
  }
 
  T7a:
  TimeNeeded = 2000;
  MoveForward();
 
  T7b:
  if (Time() == 1)
  {
    goto T8a;
  }
  else
  {
    goto T7b;
  }
 
  T8a:
  ReceiveWithLeftHand();
 
  T8b:
  if (Time() == 1)
  {
    goto T9a;
  }
  else
  {
    goto T8b;
  }
 
  T9a:
  PutDownLeftHand();
 
  T9b:
  if (Time() == 1)
  {
    goto T10a;
  }
  else
  {
    goto T9b;
  }
 
  T10a:
  ReceiveWithRightHand();
 
  T10b:
  if (Time() == 1)
  {
    goto T11a;
  }
  else
  {
    goto T10b;
  }
 
  T11a:
  PutDownRightHand();
 
  T11b:
  if (Time() == 1)
  {
    goto T1a;
  }
  else
  {
    goto T11b;
  }
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 11, 2016, 04:46 pm
"goto" is an extremely efficient way of moving around a program . . . if you're a compiler.

For us mere mortals, gotos produce hard-to-read spaghetti code, so don't use them.

Code: [Select]
  TimeNeeded = 500;
 
  WLAT1:
  if (Time() == 1)
  {
    goto WLAT2;
  }
  else
  {
    goto WLAT1;
  }
 

All you've done is moved all the blocking that was done in "delay()" out into your own code - you're still blocking.

Look at how the blink without delay avoids blocking.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: RayLivingston on Feb 11, 2016, 04:58 pm
https://en.wikipedia.org/wiki/Spaghetti_code

Regards,
Ray L.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 11, 2016, 06:05 pm
Your multiple, multiple gotos seem to be doing this:
Code: [Select]
  while(Time() != 1) {
    //wait
  }


If you get just one of those WLAT1 labels wrong or copy-paste a bit of code without thoroughly checking all the labels inside it then lots of aparrently random things will happen.

My code snippet can be pasted anywhere into the code and it won't jump to a random label elsewhere in the code. That's why gotos are bad.

It is still the wrong way to do it. If you need a delay and there is absolutely nothing else that you program needs to do at the same time, then just use the delay() function. "Waiting for motors to calibrate" is a good example where delay should be used.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 06:12 pm
Is this better? MorganS, the answer is that I intend to have other things going on, but not just yet. I am working on getting the servos to work right now, but it makes sense to go ahead and write a non-blocking version of delay() because in the near future I will add sensors to the code. I would like to implement multitasking in the near future.

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

// timer variables
unsigned long TimeNeeded;
unsigned long LastTimeUpdate = millis();

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;

  if (Time() == 1)
  {
    // down
    LeftArmDaisyChain.setServoPosition(0, 127);
    LeftArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    LeftArmDaisyChain.setServoPosition(0, 200);
    LeftArmDaisyChain.communicate();
  }

  if (Time() == 1)
  {
    // down all the way
    LeftArmDaisyChain.setServoPosition(0, 0);
    LeftArmDaisyChain.communicate();
  }
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;
 
  if (Time() == 1)
  {
    // down
    RightArmDaisyChain.setServoPosition(0, 127);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    RightArmDaisyChain.setServoPosition(0, 55);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // down all the way
    RightArmDaisyChain.setServoPosition(0, 255);
    RightArmDaisyChain.communicate();
  }
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

// time without delay()
int Time()
{
  unsigned long Interval = TimeNeeded;
  unsigned long CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  TimeNeeded = 2000;

  if (Time() == 1)
  {
    // time is up; continue
    PutDownLeftHand();
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    WaveWithLeftArm();
  }
 
  if (Time() == 1)
  {
    WaveWithRightArm();
  }
 
  if (Time() == 1)
  {
    TurnLeft();
    TimeNeeded = 1000;
  }
 
  if (Time() == 1)
  {
    TurnRight();
  }
 
  if (Time() == 1)
  {
    TimeNeeded = 2000;
    MoveForward();
  }
 
  if (Time() == 1)
  {
    ReceiveWithLeftHand();
  }
 
  if (Time() == 1)
  {
    PutDownLeftHand();
  }
 
  if (Time() == 1)
  {
    ReceiveWithRightHand();
  }
 
  if (Time() == 1)
  {
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    // continue...
  }
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Whandall on Feb 11, 2016, 06:39 pm
I would suggest to visit less marketing and more technical and programming lectures.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 06:43 pm
Very funny. I have attended none of either. I taught myself everything I know about Arduino and programming.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: el_supremo on Feb 11, 2016, 06:46 pm
For those of you who are entangled in this interminable thread, I present two data points.
- see msg #8  in http://forum.arduino.cc/index.php?topic=296831 (http://forum.arduino.cc/index.php?topic=296831)
- read the, also interminable, thread about his UNOS "operating system" http://forum.arduino.cc/index.php?topic=289888 (http://forum.arduino.cc/index.php?topic=289888)

Pete
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 06:56 pm
That was an interesting "Rube Goldberg" experiment, although I think it does have a use. I just designed it wrong and put in the wrong features. On top of that, I did not understand the AVR architecture well enough. But what does that old failed project have to do with this?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Robin2 on Feb 11, 2016, 07:10 pm
But what does that old failed project have to do with this?
See Reply #32

...R
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 07:17 pm
I saw and read it, but I do not understand. My projects were never meant to be some sort of commercial *cough* project. Rather, I posted them because I thought they were incomplete and you all (who know more than I do) could help me. I am not in it for fame or money. I am doing this purely for my own amusement although I also want to share my projects. Do you understand better now?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 11, 2016, 07:21 pm
Seems OP took Robin2 at his word in January 2015 when he said...

Quote
Take a year off
... and here we are.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 11, 2016, 07:24 pm
During that time I've been doing research and improving my programming skills, though I really could use tons of improvement still.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 11, 2016, 07:56 pm
Quote
improving my programming skills
Forget you ever heard of "goto", please.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Robin2 on Feb 11, 2016, 08:11 pm
@goodinventor, your youth and enthusiasm are wonderful.

The gap between your apparent abilities and what you aspire to is too wide for useful assistance on this Forum. To use my earlier analogy, you are like a 2nd week musician trying to participate in a guitar master class at the standard of Jimi Hendrix. You have not yet acquired either the technical skills or the background knowledge.

What concerns me is that by struggling unsuccessfully with something that is now far out of your reach you will miss the opportunity for the step-by-step acquisition of the skills that would allow you to contribute to Artificial Intelligence Research in the future.

...R
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 11, 2016, 11:10 pm
Is this better?

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

// timer variables
unsigned long TimeNeeded;
unsigned long LastTimeUpdate = millis();

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;

  if (Time() == 1)
  {
    // down
    LeftArmDaisyChain.setServoPosition(0, 127);
    LeftArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    LeftArmDaisyChain.setServoPosition(0, 200);
    LeftArmDaisyChain.communicate();
  }

  if (Time() == 1)
  {
    // down all the way
    LeftArmDaisyChain.setServoPosition(0, 0);
    LeftArmDaisyChain.communicate();
  }
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;
 
  if (Time() == 1)
  {
    // down
    RightArmDaisyChain.setServoPosition(0, 127);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    RightArmDaisyChain.setServoPosition(0, 55);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // down all the way
    RightArmDaisyChain.setServoPosition(0, 255);
    RightArmDaisyChain.communicate();
  }
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

// time without delay()
int Time()
{
  unsigned long Interval = TimeNeeded;
  unsigned long CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  TimeNeeded = 2000;

  if (Time() == 1)
  {
    // time is up; continue
    PutDownLeftHand();
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    WaveWithLeftArm();
  }
 
  if (Time() == 1)
  {
    WaveWithRightArm();
  }
 
  if (Time() == 1)
  {
    TurnLeft();
    TimeNeeded = 1000;
  }
 
  if (Time() == 1)
  {
    TurnRight();
  }
 
  if (Time() == 1)
  {
    TimeNeeded = 2000;
    MoveForward();
  }
 
  if (Time() == 1)
  {
    ReceiveWithLeftHand();
  }
 
  if (Time() == 1)
  {
    PutDownLeftHand();
  }
 
  if (Time() == 1)
  {
    ReceiveWithRightHand();
  }
 
  if (Time() == 1)
  {
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    // continue...
  }
}

I don't think that code will do what you seem to think it will do.

It certainly won't act like the code with the delays would. Ohhhhh no!

You did NOT learn the BWOD lesson but you do seem to have grasped the know-how-long-it's-been part of it. Spend some time on the implications, make 2 leds blink at different rates or 2 serial messages print at different rates, just to start.
 
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 12, 2016, 08:29 am
Here's a simple challenge I propose to people who think they've fully grasped the BWOD Principle, and you can do it on a bare Arduino: make the LED on pin 13 fade up down, without using delay.
For bonus marks, add a potentiometer and vary the fade rate.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 12, 2016, 09:01 am
Is this better? MorganS, the answer is that I intend to have other things going on, but not just yet. I am working on getting the servos to work right now, but it makes sense to go ahead and write a non-blocking version of delay() because in the near future I will add sensors to the code. I would like to implement multitasking in the near future.

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

// timer variables
unsigned long TimeNeeded;
unsigned long LastTimeUpdate = millis();

//
// Functions
//

void WaveWithLeftArm()
{
  // up
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;

  if (Time() == 1)
  {
    // down
    LeftArmDaisyChain.setServoPosition(0, 127);
    LeftArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    LeftArmDaisyChain.setServoPosition(0, 200);
    LeftArmDaisyChain.communicate();
  }

  if (Time() == 1)
  {
    // down all the way
    LeftArmDaisyChain.setServoPosition(0, 0);
    LeftArmDaisyChain.communicate();
  }
}

void WaveWithRightArm()
{
  // up
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
 
  // let motors calibrate
  TimeNeeded = 500;
 
  if (Time() == 1)
  {
    // down
    RightArmDaisyChain.setServoPosition(0, 127);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // up again
    RightArmDaisyChain.setServoPosition(0, 55);
    RightArmDaisyChain.communicate();
  }
 
  if (Time() == 1)
  {
    // down all the way
    RightArmDaisyChain.setServoPosition(0, 255);
    RightArmDaisyChain.communicate();
  }
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

void TurnLeft()
{
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void TurnRight()
{
  analogWrite(LeftFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

// time without delay()
int Time()
{
  unsigned long Interval = TimeNeeded;
  unsigned long CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  RaiseLeftHand();
  RaiseRightHand();
  TimeNeeded = 2000;

  if (Time() == 1)
  {
    // time is up; continue
    PutDownLeftHand();
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    WaveWithLeftArm();
  }
 
  if (Time() == 1)
  {
    WaveWithRightArm();
  }
 
  if (Time() == 1)
  {
    TurnLeft();
    TimeNeeded = 1000;
  }
 
  if (Time() == 1)
  {
    TurnRight();
  }
 
  if (Time() == 1)
  {
    TimeNeeded = 2000;
    MoveForward();
  }
 
  if (Time() == 1)
  {
    ReceiveWithLeftHand();
  }
 
  if (Time() == 1)
  {
    PutDownLeftHand();
  }
 
  if (Time() == 1)
  {
    ReceiveWithRightHand();
  }
 
  if (Time() == 1)
  {
    PutDownRightHand();
  }
 
  if (Time() == 1)
  {
    // continue...
  }
}

So, let me understand this, the Time() function returns true if it is more than TimeNeeded milliseconds since the last time it returned true? What if you haven't used it in a while? You can't get a negative delay.

Try and take on AWOL's challenge. It's a little fuzzy on the details so you may need to ask him for clarification but I have a solution in mind that will be only 20 lines of code.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 12, 2016, 01:25 pm
What if you haven't used it in a while?
The way the loop is written, that isn't likely to happen - there are much bigger issues with the current structure.

As it is, loop() will get called frequently. In each pass, the robot will start to raise both arms, then it will start checking whether the time has expired. Most of the time this will be false, and all of the if statements will skip their processing, and the loop will quickly exit and start over (by immediately starting to raise arms again.) finally, the time will expire, but it's impossible to predict which if statement will return first - it's pure random chance where the code will be at when millis() finally returns the target time.

The net result is that on each loop the robot will start to raise it's arms, and then every two seconds it will randomly do some other operation, but then immediately go back to the top of the loop and raise the arms again. I predict the externally visible result will be a robot that raises both arms, and then every two seconds makes a brief buzz or click as it starts to do something else and then immediately goes back to raising the arms. Or at least that's what the arm servos will do - if it happens to hit a command that tries to lower them, it will once again raise them so quickly they might not even have time to move. I don't know enough about the robot's details to know if other motors will do anything - they may do nothing, or may operate erratically or randomly.

I said that which function will trigger is completely random: that's not quite true. The odds are somewhat in favor of the first if statement, the one that puts down the arms. That's because the window of opportunity for the time to change between each if statement is small, since they are one after each other. However, after the last if statement, there is the time it takes to return from the function, loop around, re-enter the function, call the raise arms functions, and set TimeNeeded. This will all be fast, but will still take more time than evaluating each if condition - since it spends more time before this if condition than the others, there is a rather chance that millis() will hit the target time then, so the window of opportunity is larger for that first if. So the odds are higher that it will be that one that periodically triggers.

Having a bunch of delay() calls in a program like this is generally a bad idea. But using this method of timing is FAR worse!

The issue is not that delay() is inherently evil - the real problem is writing a loop() function that does a long process step by step and doesn't return until the whole sequence is done. That's what causes problems - delay() is just an easy way to make such a long blocking sequence: it's a symptom, not the disease. By re-writing delay into a Time() function, you are not solving the root problem.

Goodinventor: this is a good learning opportunity, and you should take some time to research "finite state machines" - that will be a necessary component to getting this to work properly, much more valuable than simply rewriting delay() or using multiple processors.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 01:13 am
Robin2: Perhaps I have not made myself clear on what I am currently trying to do. I am not trying to do something out of my reach. At the moment the hardware is just a little beyond my current knowledge. I need to learn a little more about finite state machines to control my robot in a simple, predictable way, I need to learn how to control servos (which I recently did), and I need to learn about a few of the basic I/O protocols (SPI, UART, I2C, and CAN). The robot at the moment is only a little more complex than a basic wheeled robot.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: jremington on Feb 13, 2016, 01:50 am
Quote
I am not trying to do something out of my reach.
Then why did you choose the rather bold title of this thread to be "Artificial Intelligence Research Project"?

Many very smart people having been working on similarly titled projects, in large groups, for several decades now, with computers many orders of magnitude more powerful than an Arduino.

And despite Steven Hawking's dire predictions, artificial intelligence doesn't seem to be a gleam in anyone's eye, let alone a pressing threat.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 01:55 am
ShapeShifter: All right, so basically my logic within loop() is all wrong. Are there any issues in the Time() function itself. I looked hard at the code for BWoD, but I cannot see a clear way to fix my code.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 01:59 am
That is the title because that is the point of this project. What I am doing now is just a step towards that end. Also, the board I am using is Arduino compatible, but it does not have an ATmega chip. Instead it has an x86 processor (full 586 instructions) with 128MB of RAM and 8MB of Flash built in. It also has a microSD card slot that supports up to 32GB. This is somewhat stronger than a typical Arduino.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Frostline on Feb 13, 2016, 04:31 am
Here's a simple challenge I propose to people who think they've fully grasped the BWOD Principle, and you can do it on a bare Arduino: make the LED on pin 13 fade up down, without using delay.
For bonus marks, add a potentiometer and vary the fade rate.
You have video of that LED fading?
After over a hour of fussing with it I tried the fade example in the IDE and it just blinked.
Fades fine on say an LED on pin 9 for example but no visible fading but just blinking on pin 13.
Tried on both an Uno and Nano (both clones though).
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Delta_G on Feb 13, 2016, 04:55 am
just blinking on pin 13.
Awfully hard to fade an LED on a pin that's not capable of PWM.

Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Frostline on Feb 13, 2016, 05:08 am
Awfully hard to fade an LED on a pin that's not capable of PWM.


Probably so.
I was just following instructions as given not thinking a mod would ask an impossible task.
I did get my fade without delay to work on pin 9 and enjoyed the challenge. 

 Was 40+ lines of code. Would like to see the around 20 line version eventually.

Word of caution to other novices like me. Either use big steps or keep to the low end of the pot. For awile I thought my code didn't work until I realized doing some math on the values I was using the fade was going to take about 36 hours.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Delta_G on Feb 13, 2016, 05:20 am
I was just following instructions as given not thinking a mod would ask an impossible task.
It's not impossible.  You just can't use analogWrite to do it.  You have to flicker the led yourself.  That's the challenge.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: RayLivingston on Feb 13, 2016, 06:01 am
Awfully hard to fade an LED on a pin that's not capable of PWM.


Actually, no.  It's not hard at all.

Regards,
Ray L.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 07:00 am
ShapeShifter: All right, so basically my logic within loop() is all wrong. Are there any issues in the Time() function itself. I looked hard at the code for BWoD, but I cannot see a clear way to fix my code.
If you don't see why that single Time() function can't work for multiple events then you need to quit fooling yourself, you have more than a little to learn about code and you are in way over your head.

Nick Gammon has tutorials that can get you started on "many things at once" and finite state machines. They're simple, complete commonsense explanations with the whys as well as the hows and whats. The addresses are in my signature space at the bottom of my post.

Learn how it works and you can know more about what doesn't work and why. At that stage you don't have to discover every mistake the hard way.

You know what Newton said about seeing farther? The giant to stand on is the work already done. Climb that and then set your sights.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 07:06 am
Awfully hard to fade an LED on a pin that's not capable of PWM.


Not at all. Human eyes are slow and Arduino is fast.

The code is BWOD with uneven and always-changing intervals at heart.

Consider that PWM is about 500Hz by default. If your total ON/OFF time always takes 2ms, the eye will be fooled, a 5 ms frame should work fine too.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 13, 2016, 08:29 am
Yes, I was forgetting that you don't have PWM on pin 13 on most Arduinos. Without analogWrite(), my solution is a bit longer than I boasted: 35 lines with comments and blank lines included.

Of course everyone's interpretation of "Fade an LED" is different. Frostline seems to be using a pot, like the AnalogInput example. My interpretation was more like the Fade example from the 01.Basics menu or the Fading example from the 03.Analog menu. [Why are there two examples almost identical?]
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 10:40 am
I took more lines than it might need, more than I thought. I could take 4 out right off the top but then changing those constants becomes a pain. It doesn't have to have the slowFade part either but I wanted to slow the fade rate.

FWIW,

Code: [Select]

const int ledPin =  13;
byte ledState = LOW;

char stepDirection = 1;
unsigned long stepNumber = 0;
const unsigned long totalSteps = 500;

byte slowFadeCount;
const byte slowFadeFactor = 2;

unsigned long startMicros;
unsigned long waitMicros;
const unsigned long pwmFrameMicros = 4000;

void setup()
{
  pinMode( ledPin, OUTPUT );
}

void loop()
{
  if ( micros() - startMicros >= waitMicros ) // will run first time
  {
    startMicros = micros();
    ledState ^= 1; // flip bit 0
    digitalWrite( ledPin, ledState );

    if ( ledState )
    {
      waitMicros = ( stepNumber * pwmFrameMicros / totalSteps );
    }
    else
    {
      waitMicros = pwmFrameMicros - waitMicros;
    }

    if ( ++slowFadeCount >= slowFadeFactor )
    {
      slowFadeCount = 0;

      if ( stepDirection > 0 )
      {
        if ( ++stepNumber >= totalSteps )
        {
          stepNumber = totalSteps;
          stepDirection = -1;
        }
      }
      else
      {
        if ( --stepNumber < 1 )
        {
          stepNumber = 0;
          stepDirection = 1;
        }
      }
    }
  }
}

Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 11:15 am
If pin 13 were hardware PWM-capable, it wouldn't have been a challenge, would it?  ;)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 01:41 pm
I will look back at the current loop() structure and the time() function more closely. I just need to write an outline to make the Time() function simpler for me to write. Then I can rework the loop() timer logic.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Delta_G on Feb 13, 2016, 03:16 pm
Actually, no.  It's not hard at all.

Regards,
Ray L.
Not for those of us who know how.  But for the guy who only knows how using analogWrite it is impossible.  That's why it is a challenge.  I was just trying to lead that poster into thinking outside the box he was in. 
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 13, 2016, 04:18 pm
Are there any issues in the Time() function itself.
The Time() function looks like it should work as designed, as an encapsulation of the BWoD logic. The limitations with it is that it can handle only a single time base at once (can only do one thing at a time.) I'm sure that as you progress with this experiment and learning process, you will want to do several things at once: move arms while rolling forward, moving the head around while waving, things like that. Each operation will require their own independent timing, and as currently written, Time() can only time one thing at a time since it uses globals for the start time and interval.

One solution would be to pass in parameters for the start time and interval (making sure you use a reference or pointer for the start time so that you can update it when the time expires.) Other solutions are to use a parameterized macro (may use more code space but less time passing arguments) or passing in a structure that describes the timer (including start time, interval, and perhaps a pointer to a function to call when the time is expired?) Or maybe a generic timing function that handles a list of timer parameter structures? The possibilities are limitless.

The main thing is that you need to get away from thinking linearly. Right now, your code basically says do this, then do that, then do the other thing. Since you have so many mechanical options in the robot, you will no doubt want to get to the point where you can do this, and sometimes do that at the same time, all while doing the other thing.

A suggestion was made to try to get two LEDs to blink at different rates. For example, blink one LED at a 500 ms rate, and the other at 510 ms. Done properly, you will see that they make a pattern that is constantly changing: sometimes blinking at the same time, sometimes blinking opposite to each other, but always changing. Blinking LEDs sounds boring, but it makes a good exercise - everyone can turn an LED on and off easily, it's just a digitalWrite() call. The advantage to using a simple output like that is it just plain works, and you can concentrate on the independent timing logic without worrying about complex outputs. Once you get that working well, you can try other timing options - for example, make one LED's period fixed, and vary the other LED based on a potentiometer input. Or blink one LED, and fade another in and out. Or make the two LEDs blink different patterns of long and short flashes (that will get you introduced into state machines, which will be invaluable to getting complex movements out of your robot.) Once you are very comfortable with the concept of doing multiple things at once, then you can replace the simple LED output with more sophisticated mechanical movements.

Then why did you choose the rather bold title of this thread to be "Artificial Intelligence Research Project"?

Many very smart people having been working on similarly titled projects, in large groups, for several decades now, with computers many orders of magnitude more powerful than an Arduino.
I don't have a problem with the thread title. It may have been more than 40 years ago, but I remember being a teenager wiring a bunch of 7400 series ICs together, and thinking that I was building a sophisticated device that would change the world! It's good to have youthful enthusiasm and to have goals, even if they are grandiose. Oh, the things I could've done back then if we had all of the cheap computers and sophisticated devices we have now. (At that age, I had heard of computers, but never saw one - they were multi-million dollar machines that took up a whole room. Microprocessor based computers were just becoming available, but they cost as much as a small car - well out of range of a teenage hobbyist.)

I have no problem with dreaming and thinking big - it's the only way that progress is made.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 05:37 pm
I know I have probably made many mistakes in my code, but what can I say? I am fairly new to the Arduino (even though I'm not new to programming in general). I have almost no way of learning robotics and programming the Arduino besides teaching myself. This is why I posted my code here- so that I may find my mistakes and improve myself without spending many hours trying to debug and learn how to do things from fragmented web pages and books. I suppose though that that is how one must learn things. Knowledge can rarely be obtained without hard work.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 06:13 pm
I know I have probably made many mistakes in my code, but what can I say? I am fairly new to the Arduino (even though I'm not new to programming in general). I have almost no way of learning robotics and programming the Arduino besides teaching myself. This is why I posted my code here- so that I may find my mistakes and improve myself without spending many hours trying to debug and learn how to do things from fragmented web pages and books. I suppose though that that is how one must learn things. Knowledge can rarely be obtained without hard work.
But what you have to remember is that few, if any of us, have your hardware, or your aims for your hardware.

So, what you're asking is for us to dry-run your code for you.

Dry-running is probably the most tedious, error-prone way of analysing code, particularly if you have no real incentive or involvement in the outcome.

If people propose improvements, I suggest you implement them before posting another block of code.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 06:20 pm
I understand that. Right now the problem is that timer implementation (which most experienced Arduino users probably know how to do correctly). The hardware-specific code is not a problem right now. I already successfully got that working. I just need help implementing something which is common to just about any Arduino system. Doing multiple things at once is of course a challenge for me, but is not unattainable considering my current level of experience. I need to find a way of creating control logic for the timers that will finish the task on schedule while also not blocking to other code from executing.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Frostline on Feb 13, 2016, 06:47 pm
Not for those of us who know how.  But for the guy who only knows how using analogWrite it is impossible.  That's why it is a challenge.  I was just trying to lead that poster into thinking outside the box he was in.  
I did try to follow that line of thinking.  I had not considered generating my own pwm signal.
My code is larger than the code offered by GoForSmoke and not smooth at slower fading rates.  But fading speed is controlled with a pot.  Now that my first attempt is done I will look to see how others have done it more efficiently and hopefully learn a better way.
Code: [Select]

const byte ledPin = 13;
const byte wiperPin = 0;
long onTime;
long potValue;
long pauseBetweenSteps;
unsigned long prevMicros = 0;
unsigned long curMicros;
unsigned long prevMillis = 0;
unsigned long curMillis;
bool accendingFade = true;
bool lightOn = true;
void flicker();

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(wiperPin, INPUT);
}
void loop() {
  potValue = analogRead(wiperPin);
  pauseBetweenSteps=potValue/100;
  flicker();
  curMillis = millis();
  if (curMillis - prevMillis >= pauseBetweenSteps) {
    prevMillis = curMillis;
    if (accendingFade == true) {
      onTime++;
      if (onTime > 2048) {
        accendingFade = false;
      }
    }
    else {
      onTime--;
      if (onTime < 1) {
        accendingFade = true;
      }
    }
  }
}
void flicker() {
  if (lightOn == true) {
    curMicros = micros();
    digitalWrite(ledPin, HIGH);
    if (curMicros - prevMicros >= onTime) {
      lightOn = false;
      prevMicros = curMicros;
    }   
  }
  else {
    curMicros = micros();
    digitalWrite(ledPin,LOW);
    if(curMicros - prevMicros >= (2048 - onTime)){
      lightOn=true;
      prevMicros=curMicros;
      }
    }
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 07:27 pm
I will look back at the current loop() structure and the time() function more closely.
Loop allows you to code for unsequenced, asynchronous events.

If you write your code as independent parts within loop then those parts can run triggering and being triggered by each other as well as by external inputs. All the parts run smoothly as long as no part uses too much time... at 16,000 cycles per millisecond, a milli is a lot of Arduino time.
   
Really, you can play this down to micros quite well despite the 4 usec granularity of micros() itself.

Quote
I just need to write an outline to make the Time() function simpler for me to write. Then I can rework the loop() timer logic.
That Time() function can only work right for one thing. If you change the interval for another, it changes for the first as well if it hasn't finished yet.

You need a start time and interval for all timed events that overlap.

C++ lets you make code objects each with its own data members like start time and interval, and function members to run them. You don't need to invent that, "just" find out what C++ Classes entail.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 08:02 pm
Now that my first attempt is done I will look to see how others have done it more efficiently and hopefully learn a better way.

You did good. You learned more than just the main lesson, I'm sure, lots of little things as well.

The micros values are good for intervals up to 90 minutes or so. For blinking leds you can go all-micros.

You're not used to the unhuman speed of these things ... yet.

1 milli = 16,000 cpu cycles.

Arduino IDE commands have a certain amount to safety written into them (slower than tight assembly code) yet still fast enough to do a few simple tasks including serial printing while averaging loop() cycling at over 50KHz. 1% of that is beyond most beginners idea of what it can do, I've seen posts from people who figured it out.

Me... I started on much slower machines, even at 1 MHz they can still be made to dance smoothly. Just trim the fat and watch them go!
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 09:01 pm
I looked at the code. I think that I need to have multiple versions of the variable LastTimeUpdate, one for each timer. I can set them to millis() when timing starts. I encapsulated these variables in a class. I was thinking something like this.

Code: [Select]

class Timer
{
  public:
  unsigned long TimeNeeded;
 
  // different timer "last time update" variables go here
  unsigned long WaveWithLeftArmTimer1LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer2LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer3LastTimeUpdate;
  unsigned long WaveWithRightArmTimer1LastTimeUpdate;
  unsigned long WaveWithRightArmTimer2LastTimeUpdate;
  unsigned long WaveWithRightArmTimer3LastTimeUpdate;
  unsigned long TurnLeftTimerLastTimeUpdate;
  unsigned long TurnRightTimerLastTimeUpdate;
  unsigned long MoveForwardTimerLastTimeUpdate;
  unsigned long LoopTimer1LastTimeUpdate;
  unsigned long LoopTimer2LastTimeUpdate;
  unsigned long LoopTimer3LastTimeUpdate;
  unsigned long LoopTimer4LastTimeUpdate;
  unsigned long LoopTimer5LastTimeUpdate;
  unsigned long LoopTimer6LastTimeUpdate;
  unsigned long LoopTimer7LastTimeUpdate;
  unsigned long LoopTimer8LastTimeUpdate;
  unsigned long LoopTimer9LastTimeUpdate;
  unsigned long LoopTimer10LastTimeUpdate;
  unsigned long LoopTimer11LastTimeUpdate;
};


Am I on the right track? If not what am I doing wrong?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 09:34 pm
I'd encapsulate for the limb, not for the timer.

Maybe that's just me.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 09:36 pm
Limb? What part of the code do you mean? The functions for movement?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 09:44 pm
Code: [Select]
WaveWithLeftArmTimer1LastTimeUpdate
Limb?


I tend to think of robots as a hierarchy of limbs and subsystems.


Also, some useful reading (https://google.github.io/styleguide/cppguide.html) (even if you don't agree with it all, it's a useful start)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 09:48 pm
Thank you! I did not know there was such a resource. So you mean you would have encapsulated code by subsystems (arms, feet, etc., for example). Does what I did solve the problem (assuming of course that I initialize the variables at the right time)?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 09:56 pm
Quote
Does what I did solve the problem
How can I know?
I don't know what the problem is.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 10:01 pm
Read Reply #45. This describes my problem. The timing logic in loop() is wrong. I think it is because I only have one variable for the start time but there are multiple places where Time() is called.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 13, 2016, 10:21 pm
Maybe the objects could be self-timing.
It would save adding a new variable to your timer code, every time you add a limb or other subsystem,
It's just a thought.

Like I said, I (and doubtless many others) don't have your hardware, or your investment in resolving whatever problems you're having, so all I'm likely to come up with are suggestions.

You can ignore them if you wish.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 10:30 pm
I could create a general class that contains variables common to all subsystems, and then use inheritance to create subclasses which contain the variables and functions for the separate parts of the robot. For example, I can have a class for the left arm of the robot which contains the pins for the servos as well as functions dealing with that part. For the timer I can split the start time variables between the body part classes based on where the corresponding Time() calls are. For the calls within loop() I can declare it either in the general class or outside of any class. Of course, if I want to do this, it would be best to use a library for these classes to simplify the code in the main program.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 13, 2016, 10:36 pm
I looked at the code. I think that I need to have multiple versions of the variable LastTimeUpdate, one for each timer. I can set them to millis() when timing starts. I encapsulated these variables in a class. I was thinking something like this.

Code: [Select]

class Timer
{
  public:
  unsigned long TimeNeeded;
  
  // different timer "last time update" variables go here
  unsigned long WaveWithLeftArmTimer1LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer2LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer3LastTimeUpdate;
  unsigned long WaveWithRightArmTimer1LastTimeUpdate;
  unsigned long WaveWithRightArmTimer2LastTimeUpdate;
  unsigned long WaveWithRightArmTimer3LastTimeUpdate;
  unsigned long TurnLeftTimerLastTimeUpdate;
  unsigned long TurnRightTimerLastTimeUpdate;
  unsigned long MoveForwardTimerLastTimeUpdate;
  unsigned long LoopTimer1LastTimeUpdate;
  unsigned long LoopTimer2LastTimeUpdate;
  unsigned long LoopTimer3LastTimeUpdate;
  unsigned long LoopTimer4LastTimeUpdate;
  unsigned long LoopTimer5LastTimeUpdate;
  unsigned long LoopTimer6LastTimeUpdate;
  unsigned long LoopTimer7LastTimeUpdate;
  unsigned long LoopTimer8LastTimeUpdate;
  unsigned long LoopTimer9LastTimeUpdate;
  unsigned long LoopTimer10LastTimeUpdate;
  unsigned long LoopTimer11LastTimeUpdate;
};


Am I on the right track? If not what am I doing wrong?
No. What happens when you set one event to happen in 10 seconds and then set up another to happen in 1?

Try learning more about classes, what they're for and how they're used and then on Arduino, avoid the dynamic allocation paradigm (including the Container Classes) like the plague.

A timer class might have private data members for start time and interval along with a public member to set the timer and one to check the timer. And then you can instantiate a timer object per event.

Or you put the timer code in the class that runs that "limb" and have the "limb" take care of itself.

With proper use of classes the entire robot code becomes a class that has its own organization built in.

One other thing, do you know about arrays? You can make arrays of objects, even inside other objects.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 13, 2016, 10:43 pm
Yes, I know how to use arrays. I'll work on the code some more.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 13, 2016, 11:05 pm
Code: [Select]

  // different timer "last time update" variables go here
  unsigned long WaveWithLeftArmTimer1LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer2LastTimeUpdate;
  unsigned long WaveWithLeftArmTimer3LastTimeUpdate;

Don't focus on the delays, concentrate on the steps you need to take. Your wave operation has four movements, with three delays between them. You don't need to implement three different delays for this, as they will not happen at the same time. Your wave process is to move from 200, to 127, to 200, to 0. There are delays between each step, but they are part of a linear sequence. A single time will work for all there.

Where you need separate timers are for situations that can run at the same time: for example waving with the left arm, while receiving with the right hand, while moving forward a set distance. Each of those three major operations will need their own timer, but any sub-operations within one of those sequences can use a common timer.

You may not be trying to do multiple things at once right now, but eventually you'll want to do that. Putting a little thought into it now will make things much simpler in the future.

You had an interesting idea in your code when you first posted your Time() function. It wasn't the Time() function, but your attempt to make it such that loop() is called many times during a single movement. This is the most interesting and important part.

Where that code fell short is that there wasn't anything to track where you were in the sequence of moves. In your original code, you kept track of your current place by having blocking delays, and linearly running one statement after another. Since we want to get away from using blocking delays, you need another way to keep track of where you are. You need to track the state of the system, which is where the previous suggestion to read up on finite state machines comes in.

improve myself without spending many hours trying to debug and learn how to do things from fragmented web pages and books. I suppose though that that is how one must learn things.
Yes, unfortunately, learning will take some research and reading. That's the way it is. Go ahead and read up on Finite State Machines, I'll wait.

Quote
Knowledge can rarely be obtained without hard work.
Very true!

OK, now that you've done the reading up on state machines.. (you did go off and do that before continuing this, didn't you?  ;D ) how would it apply here? Let's start out relatively simply and just make the code in reply #31 of this thread  (http://forum.arduino.cc/index.php?topic=374275.msg2609880#msg2609880)work they way you had intended.

We need some way to track the current state, so let's create a variable named State, and initialize it to zero. I'm going to make that variable local to the loop() function by declaring it static - that way there can be other State variables in other functions, and also being static it will remember the value from one call of loop() to the next. Now, what we need to do is look to see if the time for the current operation is up, and if so, do the next operation and advance to the next state. It could look something like this:

Code: [Select]
void loop()
{
  // A local static variable to track the current state.
  // It starts out at zero, and will remember the value between calls to loop()
  static byte State = 0;

  // Is it time to do the next operation?
  if (Time() == 1)
  {
    // The timer has expired. What happens next depends on the current state.
    switch (State)
    {
      case 0:
          RaiseLeftHand();
          RaiseRightHand();
          TimeNeeded = 2000;
          State = 1;
          break;

      case 1:
          PutDownLeftHand();
          PutDownRightHand();
          State = 2;
          break;

      case 2:
          WaveWithLeftArm();
          State = 3;
          break;

      case 3:
          WaveWithRightArm();
          State = 4;
          break;

      case 4:
          TurnLeft();
          TimeNeeded = 1000;
          State = 5;
          break;

      case 5:
          TurnRight();
          State = 6;
          break;

      case 6:
          TimeNeeded = 2000;
          MoveForward();
          State = 7;
          break;

      case 7:
          ReceiveWithLeftHand();
          State = 8;
          break;

      case 8:
          PutDownLeftHand();
          State = 9;
          break;

      case 9:
          ReceiveWithRightHand();
          State = 10;
          break;

      case 10:
          PutDownRightHand();
          State = 0;
          break;
    }
  }
}


The first time through, when the timer expires, it will call the functions to raise the left and right hands, and then update the State to 1. For the next bunch of calls to loop(), the timer won't have expired, so nothing will happen. Finally, on one of the calls to loop(), the timer will be expired, the if statement will be true, and the switch statement is entered. This time, State is 1, so the functions to put down the hands are called. Many more loop() calls will happen before the timer expires, but finally it will expire, and when the switch statement is entered, State will be 2, so the function to Wave with the left arm will be called. Finally, when the last state is done, the State variable goes to zero, and the whole operation starts over.

But there's a problem: In state 2, the WaveWithLeftArm() has a bunch of delays in it. How to handle that? Unfortunately, this post is getting to long, and I have to break things up. More to come in the next post...
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 13, 2016, 11:05 pm
OK, when were at the point where we had a problem in State 2. How to solve that?

One way is to turn it into its own little state machine, just like we did with loop(). It would have it's own static State variable, and it's own switch statement. While we are in State 2, we should keep calling WaveWithLeftArm() until it is done with its sequence - and we can do that by returning true to indicate done, false to say it needs to be called again. Make it something like this:

Code: [Select]
boolean WaveWithLeftArm()
{
  static byte State = 0;  // local state-tracking variable
  boolean done = false;   // return value, assume not done for now

  switch (State)
  {
    case 0:
        // up
        LeftArmDaisyChain.setServoPosition(0, 200);
        LeftArmDaisyChain.communicate();
 
        // let motors calibrate
        TimeNeeded = 500;

        State = 1;
        break;

    case 1:
        // down
        LeftArmDaisyChain.setServoPosition(0, 127);
        LeftArmDaisyChain.communicate();
        State = 2;
        break;

    case 2:
        // up again
        LeftArmDaisyChain.setServoPosition(0, 200);
        LeftArmDaisyChain.communicate();
        State = 3;
        break;

    case 3:
        // down all the way
        LeftArmDaisyChain.setServoPosition(0, 0);
        LeftArmDaisyChain.communicate();

        // Signal that the process is done.
        done = true;

        // Set up for the next time
        State = 0;
        break;
  }

  return done;
}



The State 2 code in the main loop() function will then need a small change to handle this return value:

Code: [Select]
      case 2:
          if (WaveWithLeftArm())
            State = 3;
          break;



Now, when in state 2, it will call WaveWithLeftArm(), which will be in state 0, so it will raise the arms and return false. When we get back to loop(), State will not be set to 3, so it will stay in State 2. The next time the timer expires, WaveWithLeftArm() will get called again, and will do the next movement, but will again return false, so loop() stays in state 2. Finally, the fourth time WaveWithLeftArm() is called, the sequence is done, and it will return true. That will cause the loop() function's State to advance to state 3, so it will move on the next time the timer expires.

There are other multi-state functions that will need the same sort of treatment. To make things general, it might be a good idea to make all of these functions return a done flag, and have all of the states check for a true return value before advancing the state. Single step functions would always return true, but multi-step functions would only return true when the sequence is done.

I didn't try to compile any of this - that's left as an exercise for the student.  8)

This is not the best nor the most efficient way of doing this. But it's a minimal change from what you have, and introduces a lot of new concepts to be learned. Once you get a good feeling for these new ideas, we can explore other ways to simplify and optimize the code. For example, encapsulate each of these little state machines into a class which exposes additional functions to modify their behavior - the base class defines the basic state operation, while the subclasses override virtual functions to implement their specific actions.

I can see many other ways to optimize and organize this, like having tables that define lists of operations, and a small bit of code to iterate through them. But those are more advanced topics, it's best to concentrate on the basics first.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 13, 2016, 11:12 pm
I could create a general class that contains variables common to all subsystems, and then use inheritance to create subclasses which contain the variables and functions for the separate parts of the robot.
Yes, that is a good long-range goal. Before doing so, it's not a bad idea to get a little more experience with the hardware, and with the state machine concepts. Those concepts will serve you well when you go to make the classes. Don't try to do too much at once, you're going to get overwhelmed.


Quote
Of course, if I want to do this, it would be best to use a library for these classes to simplify the code in the main program.
You don't have to go with a library - that just makes things more complicated and difficult to update. But it is a good idea to split things up into different files to keep related code together, but not have it all jammed into one difficult to manage file. You don't have to make libraries to do that - in the upper right of the IDE window, just below the icon for the Serial Monitor, is a little icon with a small triangle. Click it, and it will pop up a menu with a "New Tab" menu item: this lets you add a file to the project. Do a little reading up on using multiple tabs in the Arduino IDE - there are a few gotchas to watch out for. (Yes, there's that research/reading thing again...) One tip: don't name your tab main.c - it will get the IDE very confused! (Yes, I learned that one the hard way...)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 01:12 am
Here is the revised code using ShapeShifter's suggestion.

Code: [Select]

//
// Deep Think 0.0.0.2
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Perform various moves using functions.
// 2. Control the 2 D/C motors with the 86Duino.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.1.
//
// 1. Can interface with the D/C motors as well as the servos and
//    LED eyes.
// 2. Can perform various moves using functions in the program.
//

#include "MeccaBrain.h"

//
// Variables
//

// pin declarations
int LeftArmDaisyChainPin = 21;
int LEDEyePin = 29;
int RightArmDaisyChainPin = 38;
int LeftFootDCMotorPin = 11;
int RightFootDCMotorPin = 13;

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);

// timer variables
unsigned long TimeNeeded;
unsigned long LastTimeUpdate = millis();

//
// Functions
//

bool WaveWithLeftArm()
{
  static byte WaveWithLeftArmSequenceState = 0;
  bool WaveWithLeftArmSequenceDone = false;
 
  if (Time() == 1)
  {
    switch (WaveWithLeftArmSequenceState)
    {
      case 0:
        // up
        LeftArmDaisyChain.setServoPosition(0, 200);
        LeftArmDaisyChain.communicate();
     
        // let motors calibrate
        TimeNeeded = 500;
     
        WaveWithLeftArmSequenceState = 1;
        break;
     
      case 1:
        // down
        LeftArmDaisyChain.setServoPosition(0, 127);
        LeftArmDaisyChain.communicate();
        WaveWithLeftArmSequenceState = 2;
        break;
     
      case 2:
        // up again
        LeftArmDaisyChain.setServoPosition(0, 200);
        LeftArmDaisyChain.communicate();
        WaveWithLeftArmSequenceState = 3;
        break;
     
      case 3:
        // down all the way
        LeftArmDaisyChain.setServoPosition(0, 0);
        LeftArmDaisyChain.communicate();
     
        // process is done
        WaveWithLeftArmSequenceDone = true;
     
        // set up for the next time this function is called
        WaveWithLeftArmSequenceState = 0;
        break;
    }
  }
 
  return WaveWithLeftArmSequenceDone;
}

bool WaveWithRightArm()
{
  static byte WaveWithRightArmSequenceState = 0;
  bool WaveWithRightArmSequenceDone = false;
 
  if (Time() == 1)
  {
    switch (WaveWithRightArmSequenceState)
    {
      case 0:
        // up
        RightArmDaisyChain.setServoPosition(0, 55);
        RightArmDaisyChain.communicate();
 
        // let motors calibrate
        TimeNeeded = 500;
        WaveWithRightArmSequenceState = 1;
        break;
     
      case 1:
        // down
        RightArmDaisyChain.setServoPosition(0, 127);
        RightArmDaisyChain.communicate();
        WaveWithRightArmSequenceState = 2;
        break;
     
      case 2:
        // up again
        RightArmDaisyChain.setServoPosition(0, 55);
        RightArmDaisyChain.communicate();
        WaveWithRightArmSequenceState = 3;
        break;
     
      case 3:
        // down all the way
        RightArmDaisyChain.setServoPosition(0, 255);
        RightArmDaisyChain.communicate();
     
        // process is done
        WaveWithRightArmSequenceDone = true;
     
        // set up for the next time this function is called
        WaveWithRightArmSequenceState = 0;
        break;
    }
  }
 
  return WaveWithRightArmSequenceDone;
}

void RaiseLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
}

void RaiseRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
}

void PutDownLeftHand()
{
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
}

void PutDownRightHand()
{
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
}

bool TurnLeft()
{
  bool TurnLeftDone = false;
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    TurnLeftDone = true;
  }
 
  return TurnLeftDone;
}

bool TurnRight()
{
  bool TurnRightDone = false;
  analogWrite(LeftFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    TurnRightDone = true;
  }
 
  return TurnRightDone;
}

void MoveForward()
{
  analogWrite(LeftFootDCMotorPin, 255);
  analogWrite(RightFootDCMotorPin, 255);
  TimeNeeded = 3000;

  if (Time() == 1)
  {
    // continue...
  }
}

// bends at elbow with hand in front of robot
void ReceiveWithLeftHand()
{
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
}

// bends at elbow with hand in front of robot
void ReceiveWithRightHand()
{
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
}

// time without delay()
int Time()
{
  unsigned long Interval = TimeNeeded;
  unsigned long CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

void setup()
{
  // set up DC motors
  pinMode(LeftFootDCMotorPin, OUTPUT);
  pinMode(RightFootDCMotorPin, OUTPUT);
}

void loop()
{
  static byte SequenceState = 0;
 
  // check the time; change state if time is up
  if (Time() == 1)
  {
    switch (SequenceState)
    {
      case 0:
        RaiseLeftHand();
        RaiseRightHand();
        TimeNeeded = 2000;
        SequenceState = 1;
        break;
       
      case 1:
        PutDownLeftHand();
        PutDownRightHand();
        SequenceState = 2;
        break;
       
      case 2:
        WaveWithLeftArm();
        SequenceState = 3;
        break;
       
      case 3:
        WaveWithRightArm();
        SequenceState = 4;
        break;
       
      case 4:
        TurnLeft();
        TimeNeeded = 1000;
        SequenceState = 5;
        break;
       
      case 5:
        TurnRight();
        SequenceState = 6;
        break;
       
      case 6:
        TimeNeeded = 2000;
        MoveForward();
        SequenceState = 7;
        break;
       
      case 7:
        ReceiveWithLeftHand();
        SequenceState = 8;
        break;
       
      case 8:
        PutDownLeftHand();
        SequenceState = 9;
        break;
       
      case 9:
        ReceiveWithRightHand();
        SequenceState = 10;
        break;
       
      case 10:
        PutDownRightHand();
        SequenceState = 0;
        break;
    }
  }
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 14, 2016, 01:26 am
Timing is all very nice but make sure that you can stop or change motion quickly too.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 01:54 am
I need to encapsulate parts of the program to make it easier to work with and implement sensor input. Then I can start doing some really interesting things involving obstacle detection.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 14, 2016, 04:26 am
You can make a dynamic event-driven system that senses all the time, is able to move within its own freedom all the time and coordinates those all the time for 50 or more sub-tasks. Events are not just timeouts.

BTW, do the arms have sensors to tell when they have been moved and by how much?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 01:04 pm
Yes, they do. They are Smart Servos. Another feature in the library for the Smart Servos is LIM. LIM allows the robot to learn moves by the user moving the motors. The motors then just read the change in position so the move can be repeated.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 14, 2016, 01:43 pm
Yes, they do. They are Smart Servos. Another feature in the library for the Smart Servos is LIM. LIM allows the robot to learn moves by the user moving the motors. The motors then just read the change in position so the move can be repeated.
Can you interrupt these learned motions? Does the library give you options for that?

The feedback is good, is it incorporated in the motions your sketch already commands?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 01:55 pm
The library doesn't have functions specifically for interrupting tasks but the hardware I am using has BIOS (because it is a full 586 system with most of the 686 features as well). Their library appears to have been hurriedly prepared as there is frequent use of delay() and the functions dealing with the Servos use a bunch of digitalWrite calls rather than a faster interface such as Serial. My controller has 3 UART interfaces, enough to run both servo daisy chains simultaneously and have 1 extra interface. Maximum speed of the UART interfaces is 1Mbps each. My sketch so far does not incorporate LIM. It only sends output. I was just trying to figure out how to set up the servos for output. Now that I have done that, I really need to optimize the MeccaBrain library and use the sensors (the rotation sensors embedded in the servos and the ultrasonic sensor).
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 14, 2016, 02:59 pm
If the library source is open then you have hardware interface examples to work from, whoever wrote it is probably not versed in real time coding, but then most of those who buy the product won't either.

This is like the difference between chess moves and rts moves. A jerky robot is still a robot.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 08:55 pm
Very true. The library is meant to be compatible with the Arduino compatible boards in general, not optimized for a particular system and its resources. I should optimize the library for my system in particular.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 14, 2016, 10:20 pm
I just tested the code. The robot appears to be skipping some steps. Here are the results.

1. Moved arms all the way up.
2. Moved arms all the way down.
3. Moved arms all the way up.
4. Moved lower left arm backwards 90 degrees.
5. Moved arms all the way down.

It sure looks like the case 1 and case 2 code are executing but all the other code is not. I'm not exactly sure why- it could be that something is interrupting the program. Another thing I noticed was that the robot was on for quite some time before the arms started moving. I did not hook up the D/C motors for this test; I just hooked up the servos and the LED eyes for a quick test of the code (for the part that I really wanted to get right). Any ideas about what's going on? The library could also use some cleaning up.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 15, 2016, 01:16 am
I just took a look at the last code you posted, and it looks like you missed some of the subtleties of what I was trying to describe. While WaveWithLeftArm() returns true when the sequence is complete, the state 2 code in loop() that calls that function does not check the return value: it always moves on to state 3. That means that the state sequence inside WaveWithLeftArm() will get out of sync.

Furthermore, the first thing WaveWithLeftArm() does is check if Time() is returning 1: since the loop() function state 2 case is only going to be run if Time() just returned 1, and then it immediately checks Time() again in WaveWithLeftArm(), and no significant time has elapsed, Time() will always return 0 when called in WaveWithLeftArm(). That means the movement will not happen. And since it unconditionally moves on to state 3, it won't get called again.

The check for Time() is done in loop(), and it won't call any of the other functions until Time() just returned 1. There is no need to check for Time() in those functions, as it is covered by the Time() check in loop(). In fact, checking for Time() in those functions is counter-productive, as it will never return 1 given how they are called.

Go back, and look at the changes I suggested in the second half of my long post, and look carefully at your code. Notice the significant differences? You have only half of the solution implemented, and that's causing whole blocks of code to be skipped.

Once you've updated things, it can't hurt to and some Serial.print() statements to see what's happening. The first thing I would do is print out the state variable at the top of loop() just inside the Time check if statement. Then, print it out again at the bottom of loop(), after the switch statement is closed out but before that if statement closes out. That will list you see what the state is going in and coming out, and will let you see how it is progressing. You may want to do something similar on entry to each of your movement functions.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 01:21 am
OK, thanks for the help. I'll have a look at it.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 02:39 am
OK, I think I fixed the problem with loop() and also made all the movement functions return true when completed. Attached is the code.

Next I will have the program write to Serial when there is a state change or a function is completed. Then I will test the code again.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 15, 2016, 04:44 am
Very true. The library is meant to be compatible with the Arduino compatible boards in general, not optimized for a particular system and its resources. I should optimize the library for my system in particular.
You can un-delay functions. I have a technique.

I had some delay-ridden code to fix for someone else's project, serial, I2C and GSM sections. Got em.

BTW, this is a 1-shot.
You start it by setting state = initializeDevice and let undelayedFunction( state ) take it from there.
Code: [Select]
pseudocode:

short undelayedFunction ( short state ) // relies on state being kept externally, allows instant change
{
  static unsigned long startMillis, waitMillis;
 
  if ( waitMillis )
  {
    if ( millis() - startMillis < waitMillis )
    {
      return state;
    } 
    else
    {
      waitMillis = 0;
    }                       
  }

  switch ( state )
  {
    case initializeDevice :
    // dev code
    startMillis = millis();  // start timer
    waitMillis = 100; // wait 100 ms before running the device, use one per un-delay()
    state = runDevice;
    break;

    case runDevice :
    // dev code;
    state = doNothing;
    break;

    case doNothing :
  }

  return state;
}



Yup. Been there, done it, greenhouse automated 1/4 of the world away, and up there's the useful lesson.

But remember that now that function behaves differently than the original code it was hacked from.
It needs to be run in loop() with state provided and that state updated on return,

state = undelayedFunction( state ); // except don't call it just state!

And nothing else in loop blocks execution more than about 100 - 200 usecs.

Example, I have a 4x4 button matrix but I do not read all 16 buttons in 1 loop(). I read 1 button per loop() with every other function running light, loop() runs at over 50KHz. As long as it's over 1KHz, maybe even 500Hz, it shouldn't be overloaded... but I'd prefer 10+KHz loaded then co-process.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 02:56 pm
That's nice method. Thanks for sharing. I implemented Serial messages so I can see what code is being executed. I will test the code soon.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 04:16 pm
Attached is the main program with Serial messages put in.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 15, 2016, 04:25 pm
Save yourself a ton of code space
Code: [Select]
    Serial.print(F("Entering State "));
    Serial.println (SequenceState);
    switch (SequenceState)
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 04:32 pm
Thanks for showing me that optimization. Once I fix that quickly I will test the code and report back the results.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 15, 2016, 07:43 pm
That's nice method. Thanks for sharing. I implemented Serial messages so I can see what code is being executed. I will test the code soon.
Try logging to SD as part of regular operation. Time-stamp all entries, 8 hex chars does millis, and you can make a trace log to debug and tune with. You can read the card on a PC and spreadsheet or database the data, there should be lots once it all gets running.

Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 15, 2016, 08:03 pm
That's nice method. Thanks for sharing. I implemented Serial messages so I can see what code is being executed. I will test the code soon.
The GSM part of that automation code has 11 states because the original working but blocky code has 10 delays. I didn't want to write 10 case statements with time checks so I stuck 1 timer up front and used interval > 0 for the timer trigger and it sets interval = 0 on timeout, all nice and clean.

I didn't know a thing about GSM at the time. The GSM code worked at all is why my fix worked so much better. So you got the motor functions that work at all.. I wonder how many states you might need?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 08:27 pm
Logging to an SD card is a good idea. In the future I can use it for recalling past actions to help decide what to do next for the robot.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 15, 2016, 09:30 pm
I didn't want to write 10 case statements with time checks so I stuck 1 timer up front
I agree, don't have time checks all over the place. That's why I tried to limit my example to just one time check at the beginning, and then the switch statement. Actually, your code and my example are rather close to each other in principle: the big differences is that you are using the timer as a one-shot where my version is a recurring timer, and you've moved the code into a separate function (good idea) rather than keeping it in loop. Other than those details, they share pretty much the same structure and concepts.

Quote
I wonder how many states you might need?
I am trying to introduce the concept of a state machine with baby steps, using minimal changes to the original code, so that it is easy to see the progression.

Before this is done, I think he will end up with MANY states, but they won't be a linear progression as they are now. I can see groups of states that implement individual sequences (much like the current wave arm functions) and these groups of states are called at various times in response to various stimuli.

Actually, I can see this becoming several state machines: one controlling the left arm, one controlling the right arm, another for the head, others for motors, etc. Each one may be calling different sequences of states at the same time (waving with one arm while raising the other?)

For the ultimate implementation, I can see the switch statements being implemented in a series of generic state machine classes and sub-classes, or even better yet the switch statements go away altogether to be replaced with tables of states, motions, and pointers to functions to handle the individual state actions. But that's getting way ahead of ourselves, and into some much more advanced topics. Let's keep it simple for now!

Attached is the main program with Serial messages put in.
I think you're making a lot of progress, but I still see some things that are concerning. The two "wave" functions look pretty good - I can see some room for optimizing code use, but that can wait until you get further along and have the basics working (for example, each case alternative has a call to communicate, which can be done once after the switch statement closes, but that's not a big deal at this point.)

The big issue I see is that in loop(), all of your states are calling the functions twice - the first time you're ignoring the return code, the second time you're checking it to see if the sequence is done. For some operations, like raising a had, this isn't a huge issue, but it does mean that you will be sending each command twice, which is a waste of time and might cause some stuttering in the movement.

Where it becomes a problem is in the more complex movements like waving. When you first enter SequenceState 2, you will call WaveWithLeftArm(), which will perform WaveWithRightArmSequenceState state 0, and when you return to loop(), it will ignore the return value. Then it will immediately call WaveWithLeftArm() again, which will perform WaveWithRightArmSequenceState state 1. But that will happen before the movement has had a chance to complete (probably before it actually even begins to move.) The next time the timer expires, that pass through loop() will call WaveWithLeftArm() to perform state 2 and ignore the return value, and then immediately call it again to perform state 3, this time looking at the return value. It will be true, so SequenceState will advance, but the only wave states you've really given it a chance to run are states 1 and 3 -- states 0 and 2 have had no time. Furthermore, if there were an odd number of states in WaveWithLeftArm, the true value being returned at the end of the sequence would happen on that first call where the return value is being ignored, and it would be lost.

So, an important change is to update ALL of the case alternatives in loop() to get rid of the duplicate function calls - each function should only be called a single time in the state. Since all of your movement functions now return a done flag, you should keep the calls that are in the IF statements, and get rid of the ones that are standing alone. In states that call multiple functions, like state 0, it's OK to keep the AND logic in the IF statement the way you have it.

Another issue is that you still have some Time() checks inside of some functions. These are still redundant since it's being done in loop(). I don't see that any of them are required, they will just cause you to be stuck in that state forever: recalling that by definition Time() has just returned 1 to get you into loop()'s switch statement, when the function is called Time() will always return 0 since there hasn't been enough time for the timer to expire. That means that those functions which check Time() to see if the interval has elapsed will always return false. Therefore, you will be stuck in that state forever with no way to escape. You don't need to wait for Time() to be 1 in any of those simple functions, as it is already handled in the main loop. If there is something that needs to wait for time to pass before moving on to the next state, then make it a small state machine like in your wave functions.

You are performing a single sequence of states, you only need a single timer at this point, and the check for whether the timer has expired should only be done in a single place: before the main switch statement. If you feel you need to wait for some time somewhere else, you really need to be adding another state somewhere, not adding another timer or Time() check.

Once you get to the point where you're trying to do several things at once, and you have several state machines, then you will need additional independent timers (and a time check for each of the state machines) but we are not there yet.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 10:54 pm
I fixed the code again.  :) I'll now run a test on it.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 15, 2016, 11:26 pm
It looks like you have a good candidate for testing!  8)

One more suggestion for potentially useful Serial output: in loop(), at the close of the switch statement, but before the close of the if (Time() == 1) statement, print out the new state number and the time needed value. This may help you figure out why things go wrong if you end up at a strange state, and may help you figure out timing issues if one of the state functions didn't update TimeNeeded properly (or updated it when you didn't expect it.)

Change:
Code: [Select]
     case 10:
        Serial.println(F("Entering State 10."));
        
        if (PutDownRightHand())
        {
          SequenceState = 0;
        }
        
        break;
    }
  }
}


to something like:

Code: [Select]
     case 10:
        Serial.println(F("Entering State 10."));
        
        if (PutDownRightHand())
        {
          SequenceState = 0;
        }
        
        break;
    }
    Serial.print(F("New state: "));
    Serial.print(SequenceState);
    Serial.print(F("   New TimeNeeded: "));
    Serial.println(TimeNeeded);
  }
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 15, 2016, 11:35 pm
I just tested it. It is working smoothly. The only problem is that the robot is waving its arms in the exact opposite way it should! I was very amused by this. It is a quick fix though. The timing is good.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ShapeShifter on Feb 15, 2016, 11:58 pm
GREAT NEWS!
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 16, 2016, 12:15 am
I will go ahead and adjust the positions for the wave functions. Then I can begin encapsulating the timer functionality into a class (or I can adopt a different classification scheme).
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 16, 2016, 12:49 am
I've been thinking of ways to classify my timer and robot body parts systems. I can have a separate timer class and a class encompassing the robot parts which has classes inherited from it for the separate parts: i.e, the eyes, the arms, etc. It would look like this.

Code: [Select]

class Timer
{
  // declarations go here
};
class Body
{
  // declarations go here
};


The other option is that I can have separate timer systems within each body part class so that they monitor themselves. The code looks in general like this.

Code: [Select]

class Body
{
  // high-level attributes
};
class Arm : public Body
{
  // other attributes; includes its own timer system
};
// other parts go here


Which of these two classification schemes do you think is better? Is there a third, possibly better option? These are the things I am considering now.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 16, 2016, 06:31 am
Logging to an SD card is a good idea. In the future I can use it for recalling past actions to help decide what to do next for the robot.
It's invaluable.
Along with SD you get SPI bus.
SPI is 512KB/s at 1/4 speed, which lets the CPU have a few more cycles to deal with the data.

But the SD card at times can pause.
A dedicated AVR chip serving the SD can smooth that. It could buffer data to and from SPI SRAM chip(s) (they're $1 or less cheap for 8KB). A 328P can interface to Serial or I2C and run the SD and SRAM on its SPI or run the SD and SRAM on its serial bus as an SPI master and connect to another SPI bus on its SPI port as a slave... in theory it should work but be tight, the external buffer would be needed or use a 1284P which can support all that and many SD cards at once which ain't shabby for a $7 chip.

What do you think of motor routines that command tiny motions over small intervals and check on the motion feedback during the interval before commanding the next step? Would 1 ms timing be enough to make it smooth? Probably 5 ms timing would be unnoticeable, shoot for 1 or 2 at worst.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 16, 2016, 07:08 am
I fixed the code again.  :) I'll now run a test on it.
Just looking.

The pin variables, do you ever get pin > 255?

Our fingers learn to type int on PC's but PC's have RAM to waste, AVR's do not.

If you make some of those pin numbers and the arm objects into arrays, you can address them by index and save repeating code for one with more code for the other just because the names are different.

The wave with X arm functions.... no.
Derive your own arm class from the MeccaBrain class and give it functions to move with. One code for all.

Your Time() function is still wrong. A single value for interval can only time One Event at a time. The moment you try a second event with a different interval than the first, you change the timing of the first.

Build the timers into the class objects instead, or into functions as the un-delay example shows --- which btw the timer there only gets used by One Event at a time by switch(state) control!

You don't have to use unsigned long variables to time with just because millis() returns them.
For shorter intervals you can use 8 bit time ( 255 ms max, I've used them to debounce buttons) and 16 bit time, good to 65.535 seconds in millis which is enough for many needs and saves 4 bytes per timer.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 16, 2016, 07:15 am
It looks like you have a good candidate for testing!  8)

One more suggestion for potentially useful Serial output: in loop(), at the close of the switch statement, but before the close of the if (Time() == 1) statement, print out the new state number and the time needed value. This may help you figure out why things go wrong if you end up at a strange state, and may help you figure out timing issues if one of the state functions didn't update TimeNeeded properly (or updated it when you didn't expect it.)

Change:
Code: [Select]
     case 10:
        Serial.println(F("Entering State 10."));
       
        if (PutDownRightHand())
        {
          SequenceState = 0;
        }
       
        break;
    }
  }
}


to something like:

Code: [Select]
     case 10:
        Serial.println(F("Entering State 10."));
       
        if (PutDownRightHand())
        {
          SequenceState = 0;
        }
       
        break;
    }
    Serial.print(F("New state: "));
    Serial.print(SequenceState);
    Serial.print(F("   New TimeNeeded: "));
    Serial.println(TimeNeeded);
  }
}


It's better to use less verbose serial for things that may print often. Serial output buffer overflow can seriously mess with what would otherwise run fast and smooth. A single letter identifier beats a description in this case.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 16, 2016, 12:24 pm
I thought of an alternative third option for my classification. Because the Time() function will be used in all parts of the body and all parts of the body will be timing themselves, I decided to put Time() and its variables into the base class Body, while the specific classes all inherit from it. GoForSmoke: Yes, thanks for bringing that up. I'll fix that. I really only need byte for the pins. My controller has plenty of RAM though: 128MB. I have 2MB Flash to use up and so far I have used just under 160KB including the boot loader.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 16, 2016, 09:28 pm
I thought of an alternative third option for my classification. Because the Time() function will be used in all parts of the body and all parts of the body will be timing themselves, I decided to put Time() and its variables into the base class Body, while the specific classes all inherit from it. GoForSmoke: Yes, thanks for bringing that up. I'll fix that. I really only need byte for the pins. My controller has plenty of RAM though: 128MB. I have 2MB Flash to use up and so far I have used just under 160KB including the boot loader.
LOL, you should be able to run that sensor and those motors on an Uno with room for more.
That's got 32K flask and 2K RAM.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 16, 2016, 09:36 pm
True, but for my planned future additions (like a camera for vision), a Arduino Uno simply does not have the resources to run all those things effectively (the main problem would be having enough memory as the software gets more complex). 32KB Flash and 2KB RAM just aren't enough to handle what I want to do. Right now with my current program it should be able to operate fine- but when I start adding more things the memory will be used up quickly.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 16, 2016, 10:53 pm
How much of that 160KB flash used is bootloader, and how much is the sketch?
x86 is CISC with bigger instruction words so I expect fatter hex files but 160KB is Micro$oftian!

I've been thinking of ways to classify my timer and robot body parts systems. I can have a separate timer class and a class encompassing the robot parts which has classes inherited from it for the separate parts: i.e, the eyes, the arms, etc. It would look like this.

Code: [Select]

class Timer
{
  // declarations go here
};
class Body
{
  // declarations go here
};


The other option is that I can have separate timer systems within each body part class so that they monitor themselves. The code looks in general like this.

Code: [Select]

class Body
{
  // high-level attributes
};
class Arm : public Body
{
  // other attributes; includes its own timer system
};
// other parts go here


Which of these two classification schemes do you think is better? Is there a third, possibly better option? These are the things I am considering now.
Class objects are variable types, you can use them like variables though I never tried to return one from a function before, which could be interesting though I'd return a pointer to object.

You can use Timer class objects as data members in robot classes as needed and let the class member functions use that data member. 1 timer for 1 event built in.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 16, 2016, 11:08 pm
Most of that 160KB is the bootloader. It supports booting from the Flash, a USB drive, or from a microSD Card. And yes, I think it takes up a Microsoftian amount of space too.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 17, 2016, 04:03 am
My $19 Pine A64+ is due next month. 8th gen ARM.

If you give the moving parts their own controllers then the brain sends them move commands and the parts send back positional updates as they occur or "pain" messages indicating failure to move. Let the controller worry about the details and the brain to be able to change limb position goals at any time. The brain only has to send orders and get progress updates to move and can save cycles for sensing (brain jobs) and organizing, evaluating, planning, carrying out processes.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 17, 2016, 01:03 pm
My 86Duino has a servo connection interface built in along with an accelerometer and gyroscope, so I still think it would be better for controlling all the motors. Because this controller is probably overkill for just controlling a few servos and D/C motors, I will also have it read from the accelerometer and send back that data as well to whatever I decide to be the controller for the vision and learning subsystems. For this other subsystem, I was thinking of something like a Raspberry Pi 2 or a DragonBoard 410c. I think that because ARMv7 has been around so long and ARMv8 has already been released I should use an ARMv8 board, which will be supported longer.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 17, 2016, 06:31 pm
Check the kickstarter for the Pine A64, it might still be open and they're already delivering. As of June the store will be open too but pledges get perks. There's some risk with pledging but the risk is small, for me $26, and the already being shipped to others reward is greater.

That x86 board isn't enough?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 17, 2016, 06:56 pm
It's great for controlling a lot of servos and most sensors but if I ever try to implement deep learning or machine vision I may run into some performance problems. Of course, my current brain is better than is in the average entry-level humanoid.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: GoForSmoke on Feb 17, 2016, 08:04 pm
Consider a wifi robot with the big brain program running on an external desktop PC?
The bot wouldn't need to carry the power to run the brain, the frame to hold the batteries and brain and the motors capable to move all that scaled-up capability.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 17, 2016, 08:07 pm
Hmmm...not a bad idea. I would need a PC on to run the robot but it would help solve a lot of my processing power problems. Of course, I would like my robot to have some functionality without the assistance of a PC, but I can make using the PC an option for increasing processing capabilities.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 02:47 am
Hello everyone,

I have been working on turning the system functions and variables into a library, and I have run into one problem. Attached is the library. Here is an example of the compiler output error for every time I use the this keyword.

Arduino: Coding 211 (Windows 7), Board: "86Duino ONE"

In file included from Body_0_0_0_1.cpp:15:0:
Body_0_0_0_1.h:74:21: error: expected identifier before 'this'
   MeccaBrain LEDEye(this->Pin);
                     ^
Body_0_0_0_1.h:74:21: error: expected ',' or '...' before 'this'
Body_0_0_0_1.h:80:32: error: expected identifier before 'this'
   MeccaBrain LeftArmDaisyChain(this->Pin);
                                ^
Body_0_0_0_1.h:80:32: error: expected ',' or '...' before 'this'
Body_0_0_0_1.h:91:33: error: expected identifier before 'this'
   MeccaBrain RightArmDaisyChain(this->Pin);
                                 ^
Body_0_0_0_1.h:91:33: error: expected ',' or '...' before 'this'
Body_0_0_0_1.cpp: In member function 'bool LeftArm::WaveWithLeftArm()':
Body_0_0_0_1.cpp:85:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.setServoPosition(0, 200);
       ^
Body_0_0_0_1.cpp:86:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:96:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.setServoPosition(0, 127);
       ^
Body_0_0_0_1.cpp:97:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:103:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.setServoPosition(0, 200);
       ^
Body_0_0_0_1.cpp:104:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:110:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.setServoPosition(0, 0);
       ^
Body_0_0_0_1.cpp:111:7: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
       this->LeftArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp: In member function 'bool LeftArm::RaiseLeftHand()':
Body_0_0_0_1.cpp:130:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.setServoPosition(0, 200);
   ^
Body_0_0_0_1.cpp:131:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.communicate();
   ^
Body_0_0_0_1.cpp: In member function 'bool LeftArm::PutDownLeftHand()':
Body_0_0_0_1.cpp:141:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.setServoPosition(0, 0);
   ^
Body_0_0_0_1.cpp:142:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.communicate();
   ^
Body_0_0_0_1.cpp: In member function 'bool LeftArm::ReceiveWithLeftHand()':
Body_0_0_0_1.cpp:153:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.setServoPosition(1, 255);
   ^
Body_0_0_0_1.cpp:154:3: error: '((LeftArm*)this)->LeftArm::LeftArmDaisyChain' does not have class type
   this->LeftArmDaisyChain.communicate();
   ^
Body_0_0_0_1.cpp: In member function 'bool RightArm::WaveWithRightArm()':
Body_0_0_0_1.cpp:170:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.setServoPosition(0, 55);
       ^
Body_0_0_0_1.cpp:171:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:180:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.setServoPosition(0, 127);
       ^
Body_0_0_0_1.cpp:181:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:187:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.setServoPosition(0, 55);
       ^
Body_0_0_0_1.cpp:188:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp:194:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.setServoPosition(0, 255);
       ^
Body_0_0_0_1.cpp:195:7: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
       this->RightArmDaisyChain.communicate();
       ^
Body_0_0_0_1.cpp: In member function 'bool RightArm::RaiseRightHand()':
Body_0_0_0_1.cpp:214:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.setServoPosition(0, 55);
   ^
Body_0_0_0_1.cpp:215:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.communicate();
   ^
Body_0_0_0_1.cpp: In member function 'bool RightArm::PutDownRightHand()':
Body_0_0_0_1.cpp:225:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.setServoPosition(0, 255);
   ^
Body_0_0_0_1.cpp:226:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.communicate();
   ^
Body_0_0_0_1.cpp: In member function 'bool RightArm::ReceiveWithRightHand()':
Body_0_0_0_1.cpp:237:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.setServoPosition(1, 0);
   ^
Body_0_0_0_1.cpp:238:3: error: '((RightArm*)this)->RightArm::RightArmDaisyChain' does not have class type
   this->RightArmDaisyChain.communicate();
   ^
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.


After looking over the code I have realized that I have misused the this keyword and must use a different method. Unfortunately, after quite a bit of searching on the web, I still cannot find a clear answer. Could you help by giving me suggestions on how to properly use objects from a different class (in this case, a different library too) inside of a class and then access it in a function?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 02:12 pm
The header code.

Code: [Select]

//
// Body 0.0.0.1
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This is
// the header file for the main library.
//

#ifndef Body_0_0_0_1_h
#define Body_0_0_0_1_h

#include "Arduino.h"
#include "MeccaBrain.h"

class Body
{
  public:
  //
  // Variables
  //
  unsigned long TimeNeeded = 0;
  int Pin;
 
  //
  // Functions
  //
 
  // Time() will be used for all body parts, so put it up here
  // where any inherited class can access it
  int Time();
 
  private:
  // used in Time(); initialize to avoid problems with null
  // variables
  unsigned long Interval = 0;
  unsigned long CurrentTime = millis();
  unsigned long LastTimeUpdate = millis();
};

class Arm : public Body
{
  public:
  // empty for now; will be expanded later
};

class Foot : public Body
{
  public:
  bool TurnLeft();
  bool TurnRight();
  bool MoveForward();
};

class LeftFoot : public Foot
{
  public:
  // empty, but inherits Pin from class Body
};

class RightFoot : public Foot
{
  public:
  // empty, but inherits Pin from class Body
};

class Eye : public Body
{
  public:
  MeccaBrain LEDEye(this->Pin);
};

class LeftArm : public Arm
{
  public:
  MeccaBrain LeftArmDaisyChain(this->Pin);
 
  bool WaveWithLeftArm();
  bool RaiseLeftHand();
  bool PutDownLeftHand();
  bool ReceiveWithLeftHand();
};

class RightArm : public Arm
{
  public:
  MeccaBrain RightArmDaisyChain(this->Pin);
 
  bool WaveWithRightArm();
  bool RaiseRightHand();
  bool PutDownRightHand();
  bool ReceiveWithRightHand();
};

#endif


The source file.

Code: [Select]

//
// Body 0.0.0.1
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This is
// the source file for the main library.
//

#include "Arduino.h"
#include "Body_0_0_0_1.h"
#include "MeccaBrain.h"

int Body::Time()
{
  Interval = TimeNeeded;
  CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

bool Foot::TurnLeft()
{
  RightFoot TurnLeftRightFoot;
  Serial.println(F("Starting TurnLeft()."));
  bool TurnLeftDone = false;
  analogWrite(TurnLeftRightFoot.Pin, 255);
  TurnLeftRightFoot.TimeNeeded = 3000;
  TurnLeftDone = true;
  Serial.println(F("Finished TurnLeft()."));
  return TurnLeftDone;
}

bool Foot::TurnRight()
{
  LeftFoot TurnRightLeftFoot;
  Serial.println(F("Starting TurnRight()."));
  bool TurnRightDone = false;
  analogWrite(TurnRightLeftFoot.Pin, 255);
  TurnRightLeftFoot.TimeNeeded = 3000;
  TurnRightDone = true;
  Serial.println(F("Finished TurnRight()."));
  return TurnRightDone;
}

bool Foot::MoveForward()
{
  LeftFoot MoveForwardLeftFoot;
  RightFoot MoveForwardRightFoot;
  Serial.println(F("Starting MoveForward()."));
  bool MoveForwardDone = false;
  analogWrite(MoveForwardLeftFoot.Pin, 255);
  analogWrite(MoveForwardRightFoot.Pin, 255);
  MoveForwardLeftFoot.TimeNeeded = 3000;
  MoveForwardRightFoot.TimeNeeded = 3000;
  MoveForwardDone = true;
  Serial.println(F("Finished MoveForward()."));
  return MoveForwardDone;
}

bool LeftArm::WaveWithLeftArm()
{
  Serial.println(F("Starting WaveWithLeftArm()."));
  static byte WaveWithLeftArmSequenceState = 0;
  bool WaveWithLeftArmSequenceDone = false;
  switch (WaveWithLeftArmSequenceState)
  {
    case 0:
      // up
      this->LeftArmDaisyChain.setServoPosition(0, 200);
      this->LeftArmDaisyChain.communicate();
     
      // let motors calibrate
      this->TimeNeeded = 500;
     
      WaveWithLeftArmSequenceState = 1;
      break;
   
    case 1:
      // down
      this->LeftArmDaisyChain.setServoPosition(0, 127);
      this->LeftArmDaisyChain.communicate();
      WaveWithLeftArmSequenceState = 2;
      break;
   
    case 2:
      // up again
      this->LeftArmDaisyChain.setServoPosition(0, 200);
      this->LeftArmDaisyChain.communicate();
      WaveWithLeftArmSequenceState = 3;
      break;
   
    case 3:
      // down all the way
      this->LeftArmDaisyChain.setServoPosition(0, 0);
      this->LeftArmDaisyChain.communicate();
     
      // process is done
      WaveWithLeftArmSequenceDone = true;
     
      // set up for the next time this function is called
      WaveWithLeftArmSequenceState = 0;
      break;
  }
 
  Serial.println(F("Finished WaveWithLeftArm()."));
 
  return WaveWithLeftArmSequenceDone;
}

bool LeftArm::RaiseLeftHand()
{
  Serial.println(F("Starting RaiseLeftHand()."));
  bool RaiseLeftHandDone = false;
  this->LeftArmDaisyChain.setServoPosition(0, 200);
  this->LeftArmDaisyChain.communicate();
  RaiseLeftHandDone = true;
  Serial.println(F("Finished RaiseLeftHand()."));
  return RaiseLeftHandDone;
}

bool LeftArm::PutDownLeftHand()
{
  Serial.println(F("Starting PutDownLeftHand()."));
  bool PutDownLeftHandDone = false;
  this->LeftArmDaisyChain.setServoPosition(0, 0);
  this->LeftArmDaisyChain.communicate();
  PutDownLeftHandDone = true;
  Serial.println(F("Finished PutDownLeftHand()."));
  return PutDownLeftHandDone;
}

// bends at elbow with hand in front of robot
bool LeftArm::ReceiveWithLeftHand()
{
  Serial.println(F("Starting ReceiveWithLeftHand()."));
  bool ReceiveWithLeftHandDone = false;
  this->LeftArmDaisyChain.setServoPosition(1, 255);
  this->LeftArmDaisyChain.communicate();
  ReceiveWithLeftHandDone = true;
  Serial.println(F("Finished ReceiveWithLeftHand()."));
  return ReceiveWithLeftHandDone;
}

bool RightArm::WaveWithRightArm()
{
  Serial.println(F("Starting WaveWithRightArm()."));
  static byte WaveWithRightArmSequenceState = 0;
  bool WaveWithRightArmSequenceDone = false;
 
  switch (WaveWithRightArmSequenceState)
  {
    case 0:
      // up
      this->RightArmDaisyChain.setServoPosition(0, 55);
      this->RightArmDaisyChain.communicate();
     
      // let motors calibrate
      this->TimeNeeded = 500;
      WaveWithRightArmSequenceState = 1;
      break;
   
    case 1:
      // down
      this->RightArmDaisyChain.setServoPosition(0, 127);
      this->RightArmDaisyChain.communicate();
      WaveWithRightArmSequenceState = 2;
      break;
   
    case 2:
      // up again
      this->RightArmDaisyChain.setServoPosition(0, 55);
      this->RightArmDaisyChain.communicate();
      WaveWithRightArmSequenceState = 3;
      break;
   
    case 3:
      // down all the way
      this->RightArmDaisyChain.setServoPosition(0, 255);
      this->RightArmDaisyChain.communicate();
     
      // process is done
      WaveWithRightArmSequenceDone = true;
     
      // set up for the next time this function is called
      WaveWithRightArmSequenceState = 0;
      break;
  }
 
  Serial.println(F("Finished WaveWithRightArm()."));
 
  return WaveWithRightArmSequenceDone;
}

bool RightArm::RaiseRightHand()
{
  Serial.println(F("Starting RaiseRightHand()."));
  bool RaiseRightHandDone = false;
  this->RightArmDaisyChain.setServoPosition(0, 55);
  this->RightArmDaisyChain.communicate();
  RaiseRightHandDone = true;
  Serial.println(F("Finished RaiseRightHand()."));
  return RaiseRightHandDone;
}

bool RightArm::PutDownRightHand()
{
  Serial.println(F("Starting PutDownRightHand()."));
  bool PutDownRightHandDone = false;
  this->RightArmDaisyChain.setServoPosition(0, 255);
  this->RightArmDaisyChain.communicate();
  PutDownRightHandDone = true;
  Serial.println(F("Finished PutDownRightHand()."));
  return PutDownRightHandDone;
}

// bends at elbow with hand in front of robot
bool RightArm::ReceiveWithRightHand()
{
  Serial.println(F("Starting ReceiveWithRightHand()."));
  bool ReceiveWithRightHandDone = false;
  this->RightArmDaisyChain.setServoPosition(1, 0);
  this->RightArmDaisyChain.communicate();
  ReceiveWithRightHandDone = true;
  Serial.println(F("Finished ReceiveWithRightHand()."));
  return ReceiveWithRightHandDone;
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 20, 2016, 02:25 pm
Code: [Select]
class Eye : public Body
{
  public:
  MeccaBrain LEDEye(this->Pin);
};

I don't have MeccaBrain, and am unlikely to acquire one, and you didn't post the MeccaBrain header, so you're going to have to explain what you think that line does.
I read it as: "LEDEye" is a function returning something called a "MeccaBrain".

Is that correct?

Not sure what the "this>Pin" stuff is all about.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 02:55 pm
It's a constructor for a MeccaBrain object, the name of which is LEDEye.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 20, 2016, 03:01 pm
No, the constructor of a MeccaBrain object is called MeccaBrain.

That's C++ 101.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 03:33 pm
This is what I mean.

Code: [Select]

// class objects
MeccaBrain LeftArmDaisyChain(LeftArmDaisyChainPin);
MeccaBrain LEDEye(LEDEyePin);
MeccaBrain RightArmDaisyChain(RightArmDaisyChainPin);


MeccaBrain is the class object type and the rest of the code is the constructors. LeftArmDaisyChain(), LEDEye(), and RightArmDaisyChain() are all constructors of class MeccaBrain for different subsystems. My problem is actually how I am accessing the class objects though. I don't know how to properly access objects from a different class (moreover, header file) within a class. Attached are the files for the Meccabrain library.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 20, 2016, 03:52 pm
Quote
LeftArmDaisyChain(), LEDEye(), and RightArmDaisyChain() are all constructors of class MeccaBrain for different subsystems
I thought we (well, I) had established that the constructor of a class called MeccaBrain is called MeccaBrain?
If you have a derived class, then the name of the constructor is the name of the derived class.
If you think about it, how could it be otherwise? In C++, you can have multiple inheritance, so what would you call the chlid class's constructor?

Before you go much further, can I suggest you search out some basic C++ tutorials?
Maybe sign-up for a C++ MOOC.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 04:21 pm
MeccaBrain() is indeed the name of the constructor. When I declare a MeccaBrain object, I use the constructor, but my code does not look like this.

Code: [Select]

MeccaBrain MeccaBrain(Pin1);
MeccaBrain MeccaBrain(Pin2);
MeccaBrain MeccaBrain(Pin3);


That is incorrect code. Instead, it looks like this.

Code: [Select]

MeccaBrain System1(Pin1);
MeccaBrain System2(Pin2);
MeccaBrain System3(Pin3);


That is all I meant. My problem, however, is with accessing these objects in the functions, not declaring them. When I have fixed this, I will know for certain whether my declarations are right or wrong. I know the declaration system I have used is correct for two reasons. First, the tutorials I have read state the same thing, and second, I have created several programs that make use of classes with constructors. I have just never created objects from another class within a class.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 20, 2016, 04:26 pm
Quote
I have just never created objects from another class within a class.
I don't wish to appear awkward, but I'm simply not a good enough C++ programmer to talk you through this and teach you best practice.
I seriously suggest (again) that you find some good tutorials on C++ and inheritance, and work through them, and maybe pick up some proper terminology. - with your mixed-up syntax and terms, it's really hard to tell what you're trying to do.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 04:36 pm
I understand. I need to study OOP concepts more with C++, adopt a coding style, and be consistent with it.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 06:49 pm
I found out how to fix the code.

Here is the improved header file.

Code: [Select]

//
// Body 0.0.0.1
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This is
// the header file for the main library.
//

#ifndef Body_0_0_0_1_h
#define Body_0_0_0_1_h

#include "Arduino.h"
#include "MeccaBrain.h"

class Body
{
  public:
  //
  // Variables
  //
  unsigned long TimeNeeded = 0;
  int Pin;
 
  //
  // Functions
  //
 
  // Time() will be used for all body parts, so put it up here
  // where any inherited class can access it
  int Time();
 
  private:
  // used in Time(); initialize to avoid problems with null
  // variables
  unsigned long Interval = 0;
  unsigned long CurrentTime = millis();
  unsigned long LastTimeUpdate = millis();
};

class Arm : public Body
{
  public:
  // empty for now; will be expanded later
};

class Foot : public Body
{
  public:
  bool TurnLeft();
  bool TurnRight();
  bool MoveForward();
};

class LeftFoot : public Foot
{
  public:
  // empty, but inherits Pin from class Body
};

class RightFoot : public Foot
{
  public:
  // empty, but inherits Pin from class Body
};

class Eye : public Body
{
  public:
};

class LeftArm : public Arm
{
  public:
  bool WaveWithLeftArm();
  bool RaiseLeftHand();
  bool PutDownLeftHand();
  bool ReceiveWithLeftHand();
};

class RightArm : public Arm
{
  public:
  bool WaveWithRightArm();
  bool RaiseRightHand();
  bool PutDownRightHand();
  bool ReceiveWithRightHand();
};

#endif


Here is the source file.

Code: [Select]

//
// Body 0.0.0.1
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This is
// the source file for the main library.
//

#include "Arduino.h"
#include "Body_0_0_0_1.h"
#include "MeccaBrain.h"

int Body::Time()
{
  Interval = TimeNeeded;
  CurrentTime = millis();
 
  if ((CurrentTime - LastTimeUpdate) > Interval)
  {
    LastTimeUpdate = CurrentTime;
   
    // time is up
    return 1;
  }
  else
  {
    // time is not yet up
    return 0;
  }
}

bool Foot::TurnLeft()
{
  RightFoot TurnLeftRightFoot;
  Serial.println(F("Starting TurnLeft()."));
  bool TurnLeftDone = false;
  analogWrite(TurnLeftRightFoot.Pin, 255);
  TurnLeftRightFoot.TimeNeeded = 3000;
  TurnLeftDone = true;
  Serial.println(F("Finished TurnLeft()."));
  return TurnLeftDone;
}

bool Foot::TurnRight()
{
  LeftFoot TurnRightLeftFoot;
  Serial.println(F("Starting TurnRight()."));
  bool TurnRightDone = false;
  analogWrite(TurnRightLeftFoot.Pin, 255);
  TurnRightLeftFoot.TimeNeeded = 3000;
  TurnRightDone = true;
  Serial.println(F("Finished TurnRight()."));
  return TurnRightDone;
}

bool Foot::MoveForward()
{
  LeftFoot MoveForwardLeftFoot;
  RightFoot MoveForwardRightFoot;
  Serial.println(F("Starting MoveForward()."));
  bool MoveForwardDone = false;
  analogWrite(MoveForwardLeftFoot.Pin, 255);
  analogWrite(MoveForwardRightFoot.Pin, 255);
  MoveForwardLeftFoot.TimeNeeded = 3000;
  MoveForwardRightFoot.TimeNeeded = 3000;
  MoveForwardDone = true;
  Serial.println(F("Finished MoveForward()."));
  return MoveForwardDone;
}

bool LeftArm::WaveWithLeftArm()
{
  Serial.println(F("Starting WaveWithLeftArm()."));
  static byte WaveWithLeftArmSequenceState = 0;
  static MeccaBrain LeftArmDaisyChain(this->Pin);
  bool WaveWithLeftArmSequenceDone = false;
  switch (WaveWithLeftArmSequenceState)
  {
    case 0:
      // up
      LeftArmDaisyChain.setServoPosition(0, 200);
      LeftArmDaisyChain.communicate();
     
      // let motors calibrate
      this->TimeNeeded = 500;
     
      WaveWithLeftArmSequenceState = 1;
      break;
   
    case 1:
      // down
      LeftArmDaisyChain.setServoPosition(0, 127);
      LeftArmDaisyChain.communicate();
      WaveWithLeftArmSequenceState = 2;
      break;
   
    case 2:
      // up again
      LeftArmDaisyChain.setServoPosition(0, 200);
      LeftArmDaisyChain.communicate();
      WaveWithLeftArmSequenceState = 3;
      break;
   
    case 3:
      // down all the way
      LeftArmDaisyChain.setServoPosition(0, 0);
      LeftArmDaisyChain.communicate();
     
      // process is done
      WaveWithLeftArmSequenceDone = true;
     
      // set up for the next time this function is called
      WaveWithLeftArmSequenceState = 0;
      break;
  }
 
  Serial.println(F("Finished WaveWithLeftArm()."));
 
  return WaveWithLeftArmSequenceDone;
}

bool LeftArm::RaiseLeftHand()
{
  Serial.println(F("Starting RaiseLeftHand()."));
  static MeccaBrain LeftArmDaisyChain(this->Pin);
  bool RaiseLeftHandDone = false;
  LeftArmDaisyChain.setServoPosition(0, 200);
  LeftArmDaisyChain.communicate();
  RaiseLeftHandDone = true;
  Serial.println(F("Finished RaiseLeftHand()."));
  return RaiseLeftHandDone;
}

bool LeftArm::PutDownLeftHand()
{
  Serial.println(F("Starting PutDownLeftHand()."));
  static MeccaBrain LeftArmDaisyChain(this->Pin);
  bool PutDownLeftHandDone = false;
  LeftArmDaisyChain.setServoPosition(0, 0);
  LeftArmDaisyChain.communicate();
  PutDownLeftHandDone = true;
  Serial.println(F("Finished PutDownLeftHand()."));
  return PutDownLeftHandDone;
}

// bends at elbow with hand in front of robot
bool LeftArm::ReceiveWithLeftHand()
{
  Serial.println(F("Starting ReceiveWithLeftHand()."));
  static MeccaBrain LeftArmDaisyChain(this->Pin);
  bool ReceiveWithLeftHandDone = false;
  LeftArmDaisyChain.setServoPosition(1, 255);
  LeftArmDaisyChain.communicate();
  ReceiveWithLeftHandDone = true;
  Serial.println(F("Finished ReceiveWithLeftHand()."));
  return ReceiveWithLeftHandDone;
}

bool RightArm::WaveWithRightArm()
{
  Serial.println(F("Starting WaveWithRightArm()."));
  static byte WaveWithRightArmSequenceState = 0;
  static MeccaBrain RightArmDaisyChain(this->Pin);
  bool WaveWithRightArmSequenceDone = false;
 
  switch (WaveWithRightArmSequenceState)
  {
    case 0:
      // up
      RightArmDaisyChain.setServoPosition(0, 55);
      RightArmDaisyChain.communicate();
     
      // let motors calibrate
      this->TimeNeeded = 500;
      WaveWithRightArmSequenceState = 1;
      break;
   
    case 1:
      // down
      RightArmDaisyChain.setServoPosition(0, 127);
      RightArmDaisyChain.communicate();
      WaveWithRightArmSequenceState = 2;
      break;
   
    case 2:
      // up again
      RightArmDaisyChain.setServoPosition(0, 55);
      RightArmDaisyChain.communicate();
      WaveWithRightArmSequenceState = 3;
      break;
   
    case 3:
      // down all the way
      RightArmDaisyChain.setServoPosition(0, 255);
      RightArmDaisyChain.communicate();
     
      // process is done
      WaveWithRightArmSequenceDone = true;
     
      // set up for the next time this function is called
      WaveWithRightArmSequenceState = 0;
      break;
  }
 
  Serial.println(F("Finished WaveWithRightArm()."));
 
  return WaveWithRightArmSequenceDone;
}

bool RightArm::RaiseRightHand()
{
  Serial.println(F("Starting RaiseRightHand()."));
  static MeccaBrain RightArmDaisyChain(this->Pin);
  bool RaiseRightHandDone = false;
  RightArmDaisyChain.setServoPosition(0, 55);
  RightArmDaisyChain.communicate();
  RaiseRightHandDone = true;
  Serial.println(F("Finished RaiseRightHand()."));
  return RaiseRightHandDone;
}

bool RightArm::PutDownRightHand()
{
  Serial.println(F("Starting PutDownRightHand()."));
  static MeccaBrain RightArmDaisyChain(this->Pin);
  bool PutDownRightHandDone = false;
  RightArmDaisyChain.setServoPosition(0, 255);
  RightArmDaisyChain.communicate();
  PutDownRightHandDone = true;
  Serial.println(F("Finished PutDownRightHand()."));
  return PutDownRightHandDone;
}

// bends at elbow with hand in front of robot
bool RightArm::ReceiveWithRightHand()
{
  Serial.println(F("Starting ReceiveWithRightHand()."));
  static MeccaBrain RightArmDaisyChain(this->Pin);
  bool ReceiveWithRightHandDone = false;
  RightArmDaisyChain.setServoPosition(1, 0);
  RightArmDaisyChain.communicate();
  ReceiveWithRightHandDone = true;
  Serial.println(F("Finished ReceiveWithRightHand()."));
  return ReceiveWithRightHandDone;
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 20, 2016, 06:57 pm
I have a new set of errors, thankfully from my main program, not my library. The library is completely fixed.

Arduino: Coding 211 (Windows 7), Board: "86Duino ONE"

Deep_Think_0_0_0_3.ino:47:1: error: 'MainLeftFoot' does not name a type
Deep_Think_0_0_0_3.ino:48:1: error: 'MainRightFoot' does not name a type
Deep_Think_0_0_0_3.ino:49:1: error: 'MainEye' does not name a type
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Here is the main code.

Code: [Select]

//
// Deep Think 0.0.0.3
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Put the functions and variables from Deep Think 0.0.0.2 into
//    a classification scheme.
// 2. Optimize the library MeccaBrain.h so that it uses the new
//    Timer interface rather than delay().
// 3. Speed up the system by using UART rather than digitalWrite()
//    for working with the servos.
//
// Please note that this version is only intended as a demo to
// establish a basic framework for interfacing the Meccanoid
// electronic parts with the 86Duino One for future development.
// This version of the software, however, has the following
// additional capabilities compared to the previous version Deep
// Think 0.0.0.2.
//
// 1. Can operate the servos using Serial instead of
//    digitalWrite().
// 2. Can perform the MeccaBrain functions without delay().
//

#include "MeccaBrain.h"
#include "Body_0_0_0_1.h"

//
// Variables
//

// class objects
LeftFoot MainLeftFoot;
RightFoot MainRightFoot;
LeftArm MainLeftArm;
RightArm MainRightArm;
Eye MainEye;

// set variables of class objects
MainLeftFoot.Pin = 11;
MainRightFoot.Pin = 13;
MainEye.Pin = 29;

void setup()
{
  // set up DC motors
  pinMode(MainLeftFoot.Pin, OUTPUT);
  pinMode(MainRightFoot.Pin, OUTPUT);
 
  // set  up Serial
  Serial.begin(9600);
 
  // wait for Serial to be available
  while (!Serial)
  {
    // do nothing...
  }
}

void loop()
{
}


Obviously the main program is incomplete; I'm just trying to get my object declarations right.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 23, 2016, 01:18 am
After thinking about the problem I believe that I am getting errors because I have not defined a constructors for my classes. Maybe that will fix the remaining problem.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 23, 2016, 03:10 am
I have fixed the problem. The complete program is attached due to lack of space.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 24, 2016, 05:59 pm
Hello all. The next thing I will be working on is getting rid of the delay() in the MeccaBrain library and replacing it with a non-blocking version of delay(). After looking at the library, I realized that I will need to implement a non-blocking version of delayMicroseconds(). I have two options, either I can have two separate functions, TimeMillis() and TimeMicros() for the two different time units or I can use a parameter within one function to tell whether to use millis() or micros() for the timing. Using two separate functions will execute a bit faster because the if check takes some extra time, but one function may be best.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 24, 2016, 06:41 pm
Whatever do you need delayMicroseconds() for?

The usual reason why you want non-blocking delays is so that you can time functions that take milliseconds to hours, while your main loop still runs at 100-1000 times per second. This means your main loop takes 1-10milliseconds to execute. It's no point delaying 5 microseconds when your next useful unit of work will take 1000 times longer than that to do its thing.

Sometimes, a delay of a few microseconds may be required. That doesn't block your whole loop for a significant amount of time, so it's appropriate to use a blocking delay.

Think of the concept of a time budget. You have some particular sensor or motor that needs to be checked at a very defined frequency, like 100 times per second. Then all other operations must complete in less than that time so that the processor has a little 'idle' time left for overhead. Work on each function to make sure that it fits into its place in the time budget.

For really short delays, you insert a noop. (no-op, short for no operation.) This makes the processor wait just one single clock cycle. Maybe you need three clock cycles? Then add 3 noop's.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 24, 2016, 07:31 pm
I would like this because I want to be able to multitask. All time needs to be accounted for and all my delays non-blocking. Since the clock speed of my controller is 300MHz, the approximate cycle time is 3ns (too small to be practical for timing in microseconds). The microsecond delays are for calibrating the servos. I can use this time to also work on part of another task while waiting for the motors to calibrate.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 03:49 pm
After thinking over future development of the robot, at some point in the future (not right now, for the sake of simplicity), I think that using a very basic RTOS for scheduling tasks with a guaranteed deadline and managing resources for my robot would be a good idea. When I start adding more and more processes for my robot to deal with, I will have to start looking at multitasking and scheduling algorithms. When I implement these features, I will need a system for locking down resources to prevent data races and multiple processes trying to access a single resource at the same time. I think that using a simple RTOS will help make this design simpler and easier to develop. I can then include my application in multiple files and call up different subsystems whenever I need them. Of course, I will want to have a log to give me feedback. I'll use a file on an SD card and log to it for now, so I won't need to have the robot connected to the computer. In the near future I think using WiFi to report back actions to the computer would be a good idea.

In terms of hardware, I need an easier way to hook up the controller I am using to the robot, since the kit was obviously not designed for this. I thought maybe I can design a simple case that attaches directly to the back of the Meccanoid G15 and have it 3D printed. This would make hooking up things much less of a hassle. For my power supply I think a large capacity USB power bank would be a good idea (maybe around 2000 - 4000 mAh would be a good idea?). I know that the controller by itself draws 400mAh. Unfortunately, the Meccano sources for their Smart Modules do not specify how much current they draw. I'm guessing it's around 200mAh for each one (I know servos draw a lot of power), and there's 4 of them, so the total power draw of the controller plus the 4 servos is 1200mAh. In the future I would like to get more servos in order to have the robot actually walk, but right now I need to learn more about the stuff I am currently working with. I am currently improving the MeccaBrain library to make it faster by using Serial instead of basic I/O. Once I do this I can focus on sensor input.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 26, 2016, 03:54 pm
the controller by itself draws 400mAh.
Bzzzzzzt.....

You don't draw mAh


Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 03:56 pm
I was referring to current consumption. Milliamps per hour is a measurement of current consumption.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 26, 2016, 04:00 pm
Milliamps per hour
¿Que?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 04:05 pm
I'm sorry, but I don't speak Spanish. I only know two languages: English and Latin.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Robin2 on Feb 26, 2016, 05:04 pm
I was referring to current consumption. Milliamps per hour is a measurement of current consumption.
No it's not.

Milliamps is a measure of current.

Milliamp-hours is a measure of current multiplied by time. If you also multiply it by volts you get milliwatt-hours which is a measure of energy.

...R
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 05:13 pm
Correct. The 400mAh refers to how much current the controller uses per hour under typical conditions. That's what I mean by "current consumption". It refers to how much current is used up in a given amount of time; in this case the unit for current is milliamps and the unit for time is hours. The unit I am using is milliamps per hour, or mAh, which is a typical unit used to measure the current used in electronics.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 26, 2016, 05:36 pm
Correct. The 400mAh refers to how much current the controller uses per hour under typical conditions. That's what I mean by "current consumption". It refers to how much current is used up in a given amount of time; in this case the unit for current is milliamps and the unit for time is hours. The unit I am using is milliamps per hour, or mAh, which is a typical unit used to measure the current used in electronics.
At the risk of repeating myself, ¿Que?

You need to back up a little and get some basics correct.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 05:47 pm
Quote
At the risk of repeating myself, ¿Que?

You need to back up a little and get some basics correct.
Yes, such as the fact that I don't know Spanish yet.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: Robin2 on Feb 26, 2016, 06:43 pm
The unit I am using is milliamps per hour, or mAh, which is a typical unit used to measure the current used in electronics.
The word "per" implies division as in miles-per-hour and miles-per-gallon

mAh involves multiplication.

mAh-per-hour would be valid - but it simplifies to milliamps

...R
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 06:50 pm
Oh, OK. I messed up the name, that's all. Thanks for telling me. My bad. Besides that, what do you think?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 26, 2016, 09:23 pm
Quote
I messed up the name, that's all.
No, you messed up the concept.

You can't simply make up your own definitions of commonly-accepted terms, and expect others to recognise your understanding   of them.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 26, 2016, 10:51 pm
In this case the name and the meaning go hand in hand, so yes, that is true. OK, now that I have received a brief correction on terminology, what about the idea itself that I mentioned?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 03:17 am
I created a non-blocking system for timing in microseconds as well as milliseconds and re-worked the MeccaBrain library so that it uses these non-blocking functions. Next I will try to implement UART instead of digital I/O to interface with the servos.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 27, 2016, 03:54 am
now that I have received a brief correction on terminology
I think you have a demonstrated a lack of understanding of the concepts power and energy, actually.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 03:43 pm
I'm beginning to think that for future ease of use I should use smart pointers for all my pointer declarations. That way I will not have to worry about manually deleting them when they need to be deleted. It will also make my code a bit simpler.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 10:07 pm
I implemented smart pointers into my program and replaced the Serial calls for the main loop with logging to the SD card. Next I will work on getting the servos to use UART instead of general purpose I/O. The main thing I would like to know is what is the UART equivalent of HIGH and LOW for digitalWrite()? I have tried to find out myself but so far have had no luck.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 27, 2016, 10:09 pm
Quote
Next I will work on getting the servos to use UART instead of general purpose I/O. The main thing I would like to know is what is the UART equivalent of HIGH and LOW for digitalWrite()?
Don't understand the question.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 10:14 pm
When using digitalWrite() there are two states where you can write to a pin: HIGH or LOW. However, suppose I want to use Serial to write to the pin rather than digitalWrite(). What values should I send to the pin to tell it to go HIGH or LOW?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 27, 2016, 10:17 pm
Well, there's only one pin you can write to with Serial,  so what do you think?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 10:22 pm
Serial.write(1) for HIGH and Serial.write(0) for LOW? I think that's a fairly safe guess.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 27, 2016, 10:32 pm
Stop guessing.
Either start testing or start reading.


I really don't have a clue what you're trying to do.
I suspect you don't either.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 27, 2016, 10:38 pm
In the MeccaBrain library within certain functions, there are calls to digitalWrite() to communicate with the servos. What I would like to do is use Serial to communicate (send the values) to the servos instead of "normal" I/O (i.e. GPIO). In order to do this, I need a way of sending the equivalent of HIGH and LOW using Serial instead of digitalWrite(). Here are what I think are the equivalent code snippets.

Code: [Select]

digitalWrite(SomePin, HIGH);
digitalWrite(SomePin, LOW);


Code: [Select]

Serial.write(1);
Serial.write(0);
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 27, 2016, 10:42 pm
Yeah, I think by now you know how we feel about snippets.
Quote
In the MeccaBrain library within certain functions, there are calls to digitalWrite() to communicate with the servos.
You're assuming we know what a MeccaBrain is, or what a MeccaBrain library looks like.

You need to read up on serial comms and PWM for servos.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: el_supremo on Feb 28, 2016, 12:05 am
Quote
What I would like to do is use Serial to communicate (send the values) to the servos
Why?
Specifically - what do you think using Serial is going to do for you that "general purpose I/O" doesn't/can't?

Pete
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 01:05 am
Code: [Select]

Why?
Specifically - what do you think using Serial is going to do for you that "general purpose I/O" doesn't/can't?


Speed gains. My controller has 3 Serial interfaces, each with a maximum baud rate of 3,000,000. This allows for fast communication and frees up my GPIO pins for other things. If you think there is something wrong with my opinion, please feel free to speak up.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 28, 2016, 02:20 am
That makes no sense. If you do Serial.write(1) the pin ges briefly high, then low for 7 bit periods, then high and again low. Serial sends a sequence or pattern.

You can use the serial pins as general purpose I/O but serial is so much more useful, that you don't normally waste those pins on just high and low.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 02:36 am
I have three Arduino-style Serial interfaces, as well as an RS-485 Serial interface which software-wise is controlled in the same manner. The reason why I even considered using Serial instead of GPIO is that the Serial interfaces each operate at 3MHz whereas the GPIO operate at up to 150KHz (a 20x difference!). If I use the Serial for the servos, the speeds will be much quicker. On the other hand, if I find a more suitable use for Serial, then I may very well not use it for controlling the servos.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Feb 28, 2016, 02:58 am
No and no. You are confusing different concepts.

IF serial works at 3MHz (and I don't believe it does) then you still have to send 8 bits plus the framing bits to send one piece of information. So there is a factor of ten slower than your naive calculation.

GPIO works much faster than that. 8MHz is possible, but you lose some of the convenience of digitalWrite(). 

What kind of servos? Normal hobby servos don't work that way anyway. You can't make the servo faster by sending data faster. It's just not possible.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 03:14 am
Of course. Different servos operate at up to certain speeds. The servos I am using need a 417 microsecond wait time between each sent bit. The servos were a little slow on the response, but from the theoretical speed I think the real barrier here is the software, not the hardware. I think that if I can find a more efficient way of getting the servos going I will see a lot less overhead.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 28, 2016, 09:39 am
417 microseconds sounds awfully like 2400 bits per second.
That's a long way short of 3000000 bits per second.
So, you can send 240 characters per second to these serial controlled servos(?).
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 01:27 pm
Even a little less than that, because it takes time to send the signals and for the servo to interpret them.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 28, 2016, 05:42 pm
I don't see where this discussion is going.
If these servos expect data at 2400 bits per second, talk of 3Mbps is hand-waving and WIBNIs - it's like expecting your car to do 500kph because you put fuming red nitric acid in the tank instead of petrol.

Quote
The servos I am using need a 417 microsecond wait time between each sent bit
Either you've misread something, or you've just halved the effective data rate.

Quote
If you think there is something wrong with my opinion, please feel free to speak up.
It's OK to have opinions, but when they're based on partial truths or misapprehensions, they're not worth very much.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 07:51 pm
Quote
It's OK to have opinions, but when they're based on partial truths or misapprehensions, they're not worth very much.
As many opinions are. So basically in this case I should save the Serial pins for a better use and keep the old digitalWrite() system.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 28, 2016, 08:21 pm
So basically in this case I should save the Serial pins for a better use and keep the old digitalWrite() system.
Who knows?
You maybe?
You have a board and a robotic kit few others here seem to use.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 09:23 pm
This API looks like it would be well suited to my project. http://www.ros.org/ (http://www.ros.org/)

It happens to support the Arduino as well as my own board. There is a system for setting up multiple microcontrollers for parallel processing as well as many other features. Of course, right now I don't need something like that for what I'm currently trying to do, but once I add more advanced features such as visual processing it would be a good idea.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 28, 2016, 09:27 pm
This API looks like it would be well suited to my project. http://www.ros.org/ (http://www.ros.org/)

It happens to support the Arduino as well as my own board. There is a system for setting up multiple microcontrollers for parallel processing as well as many other features. Of course, right now I don't need something like that for what I'm currently trying to do, but once I add more advanced features such as visual processing it would be a good idea.
And . . . another tangent.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 28, 2016, 10:22 pm
Quote
And . . . another tangent.
You consider that off-topic?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: JimboZA on Feb 29, 2016, 04:42 am
You consider that off-topic?
I'm not sure this thread even has a topic... more like a diary of OP's ramble through the countryside.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 29, 2016, 08:20 am
You consider that off-topic?
Did I say it was off-topic?
Same topic, another lurch in a different direction.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 29, 2016, 01:01 pm
Quote
Did I say it was off-topic?
Same topic, another lurch in a different direction.
There are a lot of things to consider, which is why this conversation looks like this.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Feb 29, 2016, 01:06 pm
Here's an idea: You start a blog, for yourself, and if and when you've got something that you need answering (and not something random you thought of on the spur of the moment), or really neat to show and share, you post that thing, with context, here.
That way, it doesn't look like you're using a forum as a blog, which is how it's going at the moment.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Feb 29, 2016, 01:52 pm
OK. Thanks for the advice.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 01, 2016, 03:25 am
I tested the new code. It for some reason is not working. I checked the SD card for the log and found out that the log file was apparently never created. This means something went wrong during the initialization period. Or it could have something to do with the robot not having enough power. Can you see anything wrong with my code during the initialization, specifically the SD card and the servos? Thank you for your help.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 01, 2016, 09:25 am
Quote
The library supports FAT16 and FAT32 file systems on standard SD cards and SDHC cards. It uses short 8.3 names for files.
Code: [Select]
File LogFile = SD.open("Deep_Think_0_0_0_2_Log.txt", FILE_WRITE);
Can you count to eight?

Personally, I'd open the file inside "setup()"
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 02:34 am
Quote
Personally, I'd open the file inside "setup()"
Unfortunately, this is not an option, since the File object LogFile becomes out of scope if I do this. Are there any crucial things I am doing wrong here?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 08:31 am
Quote
Unfortunately, this is not an option, since the File object LogFile becomes out of scope if I do this
{facepalm}
I said move the "open" into "setup", not the definition.

Quote
Are there any crucial things I am doing wrong here?
Other than not being able to count past seven?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 01:01 pm
Quote
Other than not being able to count past seven?
Where did you get that quote you mentioned earlier from? If it was from me, I know it is a typo error. Yes, I do, in fact, know how to count past seven.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 01:21 pm
Where did you get that quote you mentioned earlier from? If it was from me, I know it is a typo error. Yes, I do, in fact, know how to count past seven.
OK, count the number of characters in "Deep_Think_0_0_0_2_Log.txt"
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 01:33 pm
Quote
OK, count the number of characters in "Deep_Think_0_0_0_2_Log.txt"
Do you wish for me to include the quotes or no?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 01:39 pm
It makes little difference, does it?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 01:48 pm
Without quotes it is 26 characters long.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 01:52 pm
And the $64000 question is - "Is that longer or shorter than the allowed 8.3 filename?"
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 02:02 pm
26 > 8.3, although it cannot be compared with 8.3 in this case because there is no size "8.3" for variables. It must be an integer.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 02:05 pm
Eight-dot-three refers to the DOS filename format supported by the SD library, pointed out in reply #186.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 02:10 pm
Aha! So my file name needs to be made shorter, right?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 10:11 pm
Is this what you are talking about? Are there any other issues besides that?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 10:18 pm
Code: [Select]
LogFile = SD.open("Deep_Think_Log_0_0_0_3.txt", FILE_WRITE);
Do the logging after starting the initialisation of the thing you're debugging?
No.
Not clever.

And that filename - you've really not been paying attention, have you?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 10:26 pm
I'm pretty sure I cannot open a file before the SD card interface is even initialized. Is that correct? I changed the file name to a shorter one: "log.txt".
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on Mar 03, 2016, 10:29 pm
Code: [Select]
// set up DC motors (feet)
  if (MainLeftFoot.SetLeftFootPin(LEFT_FOOT_PIN))
  {
    if (MainRightFoot.SetRightFootPin(RIGHT_FOOT_PIN))
    {
      // set up the arms
      if (MainLeftArm.SetLeftArmPin(LEFT_ARM_PIN))
      {
        if (MainRightArm.SetRightArmPin(RIGHT_ARM_PIN))
        {
          // set up eye
          if (MainEye.SetEyePin(LED_EYE_PIN))
Do the logging after starting the initialisation of the thing you're debugging?

Is that any clearer?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 10:32 pm
Got it! So I initialize the SD card and open the file before I set up the DC motors in setup().
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 03, 2016, 11:43 pm
After doing some research, it appears that my board doesn't write to the SD card because the program built into the Flash never runs. The board automatically tries to boot from the SD card first, so it could be that it is doing nothing because no program is on the SD card and not executing the code on the built-in Flash. I think I can work around this by using ROS, which handles the SD card work for me, in my program. There is a debug message system for use on the SD card and a better solution for encapsulating different parts of the robot. I'll try this and get back to you on how it went.

Thank you,
goodinventor
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 05, 2016, 07:53 pm
To simplify things I removed the SD card log calls so I could identify the problem. It seems that the power source I am using (a 9V battery) doesn't supply enough current for my controller, servos, and other electronics. I will see if I can find a power supply that has enough current (I'm thinking 2A at least for everything). Meanwhile I will also work on implementing a basic sensor system and create a simple event-driven program for controlling the servos based on sensor input. For this I will use the ROS API along with my own libraries.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: MorganS on Mar 05, 2016, 09:49 pm
This is kind of a big robot isn't it?  2A will only run one or two servos. Add up the power consumption of all your components, add 25% for safety and get a power supply with more amps than that.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 05, 2016, 10:16 pm
I was thinking of 2A as minimal. I prefer 3A at least because I expect to add more stuff in the future. It also wouldn't be a bad idea to reinforce it with some form of renewable energy, such as a solar panel to charge my main battery.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Mar 05, 2016, 11:52 pm
I am working on using ROS to drive the robot, but I have run into one problem. Here is the output generated by the compiler.

Arduino: Coding 211 (Windows 7), Board: "86Duino ONE"

Deep_Think_0_0_0_4.ino:104:1: error: 'LeftFoot' does not name a type
Deep_Think_0_0_0_4.ino:105:1: error: 'RightFoot' does not name a type
Deep_Think_0_0_0_4.ino:106:1: error: 'LeftArm' does not name a type
Deep_Think_0_0_0_4.ino:107:1: error: 'RightArm' does not name a type
Deep_Think_0_0_0_4.ino: In function 'void setup()':
Deep_Think_0_0_0_4.ino:122:7: error: 'MainLeftFoot' was not declared in this scope
Deep_Think_0_0_0_4.ino:124:9: error: 'MainRightFoot' was not declared in this scope
Deep_Think_0_0_0_4.ino:127:11: error: 'MainLeftArm' was not declared in this scope
Deep_Think_0_0_0_4.ino:129:13: error: 'MainRightArm' was not declared in this scope
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Attached are the files. I did not have this problem last time, so what do you think is wrong? For adding these libraries I used "New Tab" in the IDE.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 09, 2016, 12:49 am
I have recently started working on the machine learning part of the software. I am using a basic logistic regression algorithm for now. I compiled and loaded the program successfully (see below), but I get no output. After looking over it myself, I could not figure out why there was no output shown, so I am posting it here in hopes that a second pair of eyes (or even more) can point out to me the problem. For your information, no outputs are used except the Serial (for the Serial monitor only), so you should be able to run this program on most Arduino and Arduino-compatible boards. Thank you all!

Code: [Select]

//
// Deep Think 0.0.0.5
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Implement a basic deep learning algorithm (created by the
//    programmer) to choose what course of action to take (a
//    limited number of options).
// 2. Implement a basic system for conversation via the Serial port
//    (this means the robot generates output in response to the
//    user's input).
//
// This version of the program starts dealing with a different
// problem than the previous versions. It handles the
// intelligence aspect of the robot rather than the motors and
// sensors. Later versions will incorporate both once the
// intelligence capabilities have matured. I expect this will be a
// valuable learning process that will help the project succeed in
// the future.
//

//
// Preprocessor Section
//

//
// Let the file be included only once in compilation.
//
#pragma once

//
// Makes sure the appropriate compiler is being used.
//
#ifndef __cplusplus
  #error "A C++ compiler is required."
#endif

//
// Makes sure the appropriate Arduino header is included.
//
#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//
// The other necessary headers are included here.
//
#include <vector>

//
// Namespaces
//
using namespace std;

//
// Classes
//

class Node
{
  public:
    //
    // This is the training set for use of the algorithm. It contains
    // the y values for every integer value of x (starting with 1 and
    // going on up).
    //
    vector<float> TrainingSet;
       
    //
    // The output set for the cost function values.
    //
    vector<float> CostFunctionOutputSet;
   
    //
    // Loads the training data set.
    //
    void LoadTrainingSet()
    {
      TrainingSet.push_back(1.0);
      TrainingSet.push_back(1.1);
      TrainingSet.push_back(1.3);
      TrainingSet.push_back(1.3);
      TrainingSet.push_back(1.4);
    }
   
    vector<float> CalculateCostFunction(vector<float> training_set)
    {
      //
      // Creates containers for place of the next y value element,
      // the x value, and the y value.
      //
      int y_element = 1;
      float x_value = 1.0;
      float y_value = training_set.at(y_element);
     
      //
      // Loops through and calculates the cost function for the values
      // in the training set.
      //
      for (x_value = 0.0; x_value <= 1.4; x_value += 0.1)
      {
        //
        // Create a value for the sum to update the cost function value
        // for each successive x value.
        //
        float CurrentSumCostFunctionValue = 0;
       
        //
        // Here is the formula for evaluating the cost function value.
        //
        float CostFunctionValue = (1 / (2 * training_set.size())) * (pow(2 * x_value - y_value, 2));
       
        //
        // Update the sum here.
        //
        CurrentSumCostFunctionValue += CostFunctionValue;
       
        //
        // Add an element to the output vector which contains the updated
        // sum value. These values will show how each successive iteration
        // of the algorithm (logistic regression in this case) will affect
        // the  progress of the learning.
        //
        CostFunctionOutputSet.push_back(CurrentSumCostFunctionValue);
      }
    }
};

//
// Class Objects
//

//
// Create a Node class object here.
//
Node *MyNode;

void setup()
{
  Serial.begin(9600);
 
  //
  // Here is our x value which will be updated to create a table
  // of values later.
  //
  float OutputTableXValue = 0;
 
  Serial.println("x Value   Cost Value");
  delay(100);
 
  //
  // Now print the contents of the output vector for analysis.
  //
  for (vector<float>::const_iterator i = MyNode->CostFunctionOutputSet.begin(); i != MyNode->CostFunctionOutputSet.end(); ++i)
  {
    Serial.print(OutputTableXValue);
    delay(100);
    Serial.print("       ");
    delay(100);
    Serial.print(*i);
    delay(100);
  }
}

void loop()
{
}


Regards,
goodinventor
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: pert on May 09, 2016, 03:14 am
I couldn't test it because "fatal error: vector: No such file or directory" but I'd just start commenting things out until it starts working and then add things back in until you find out what is causing the problem.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: AWOL on May 09, 2016, 08:27 am
Quote
, but I get no output.
Because you've got no input?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 09, 2016, 02:41 pm
I couldn't test it because "fatal error: vector: No such file or directory" but I'd just start commenting things out until it starts working and then add things back in until you find out what is causing the problem.
It is one of the C++ standard libraries. I suppose then that the Arduino environment really doesn't support some of the standard libraries.

Because you've got no input?
I just set up some Serial output so that I can make sure the cost function is working. I still have a whole other process to get working (the gradient descent part). I decided to check each function as I program it so that I can troubleshoot more effectively.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: pert on May 09, 2016, 02:44 pm
Yes, I found some instructions for how to install it but wasn't that motivated.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 09, 2016, 04:27 pm
Yes, I found some instructions for how to install it but wasn't that motivated.
I understand that. You probably see little point in going through that much trouble to troubleshoot someone else's problem.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: ChrisTenone on May 10, 2016, 11:03 am
I understand that. You probably see little point in going through that much trouble to troubleshoot someone else's problem.
When posted code doesn't compile, it's easy to understand why folks wouldn't want to alpha-test it, right? I mean, then say someone found something else that didn't work as expected. Would your reply be another admonition to the tester?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 10, 2016, 12:17 pm
When posted code doesn't compile, it's easy to understand why folks wouldn't want to alpha-test it, right? I mean, then say someone found something else that didn't work as expected. Would your reply be another admonition to the tester?
Exactly. My code probably still has lots of bugs since I'm not getting any feedback from the terminal. This means that either something was wrong with the connection to the terminal (I doubt it though since I tested it several times) or my output code never executed properly (somewhere my execution is cut off). I think the second problem is much more likely.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 19, 2016, 10:24 pm
I have a full implementation now. I get the following output.

Code: [Select]

Starting...
Computing gradient descent...


My problem is that it doesn't return the values of MyNode->theta_0 and MyNode->theta_1. Any ideas on what I am doing wrong? The code is below.

Code: [Select]

//
// Deep Think 0.0.0.5
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Implement a basic deep learning algorithm (created by the
//    programmer) to choose what course of action to take (a
//    limited number of options).
// 2. Implement a basic system for conversation via the Serial port
//    (this means the robot generates output in response to the
//    user's input).
//
// This version of the program starts dealing with a different
// problem than the previous versions. It handles the
// intelligence aspect of the robot rather than the motors and
// sensors. Later versions will incorporate both once the
// intelligence capabilities have matured. I expect this will be a
// valuable learning process that will help the project succeed in
// the future.
//

//
// Preprocessor Section
//

//
// Let the file be included only once in compilation.
//
#pragma once

//
// Makes sure the appropriate compiler is being used.
//
#ifndef __cplusplus
  #error "A C++ compiler is required."
#endif

//
// Makes sure the appropriate Arduino header is included.
//
#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//
// The other necessary headers are included here.
//

//
// Namespaces
//
using namespace std;

//
// Classes
//

class Node
{
  public:
    //
    // This is to keep track of xi and yi during the summation.
    //
    int col = 0;
   
    //
    // Here is the training set size, which will be used in the calculations.
    //
    int TrainingSetSize = 3;
   
    //
    // Here is the learning rate, which will be adjusted by
    // experimentation until the desired results are achieved.
    //
    float LearningRate = 0;
   
    //
    // Here is the training set to test the algorithm.
    //
    float TrainingSet[2][3] =
    {
      {1.0, 2.0, 3.0}, // row 0 = 1.0, 2.0, 3.0
      {1.0, 2.0, 3.0}  // row 1 = 1.0, 2.0, 3.0
    };
   
    //
    // These variables denote the ith element of x and y
    // respectively in the training set, where x corresponds
    // to row 0 in the training set and y corresponds to row
    // 1 in the training set.
    //
    float xi = TrainingSet[0][col];
    float yi = TrainingSet[1][col];
   
    //
    // These variables are used in the hypothesis function. For this
    // machine learning example h_theta(x) = theta_0 + theta_1 * x.
    //
    float theta_0 = 0;
    float theta_1 = 0;
   
    //
    // Compute the hypothesis function.
    //
    float h_theta(float xi)
    {
      return (theta_0 + theta_1 * xi);
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi)^2, where
    // h_theta(xi) is the hypothesis function of the ith element
    // of x in the training set (xi) and yi is the ith element of
    // y in the training set. This function will be used to
    // compute the cost function.
    //
    float ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += pow(h_theta(xi) - yi, 2);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the summation of xi * (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += xi * (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the cost function.
    //
    float ComputeCostFunction()
    {
      float cost = (1 / (2 * TrainingSetSize)) * ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      return cost;
    }
   
    //
    // Updates theta_0 and theta_1 using gradient descent.
    //
    void UpdateGradientDescent()
    {
      //
      // We can't assign the values directly to theta_0 and theta_1 because they are dependent
      // on each other, therefore the assignment must be simultaneous.
      //
      float new_theta_0 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      float new_theta_1 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(TrainingSetSize);
     
      theta_0 = new_theta_0;
      theta_1 = new_theta_1;
    }
};

//
// Class Objects
//

//
// Create a Node class object here.
//
Node *MyNode;

void setup()
{
  Serial.begin(9600);
 
  while (!Serial)
  {
    ; // wait for Serial port to connect
  }
 
  //
  // Test to make sure Serial is working.
  //
  Serial.println("Starting...");
}

void loop()
{
  Serial.println("Computing gradient descent...");
 
  //
  // Update theta0 and theta1 using gradient descent.
  // ComputeCostFunction is not used here, since the gradient
  // descent algorithm incorporates it (partial derivative
  // of the cost function for j = 0 and j = 1 for theta_j),
  // although it is included since it will likely be used later.
  //
  MyNode->UpdateGradientDescent();
 
  //
  // Print results for observation and analysis.
  //
  Serial.print("theta_0");
  delay(1000);
  Serial.println(MyNode->theta_0, DEC);
  delay(1000);
  Serial.print("theta_1");
  delay(1000);
  Serial.println(MyNode->theta_1, DEC);
  delay(2000);
}
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: el_supremo on May 19, 2016, 10:41 pm
It prints this for me on a Nano:
Code: [Select]
Starting...
Computing gradient descent...
theta_00.0000000000
theta_10.0000000000
Computing gradient descent...
theta_00.0000000000
theta_10.0000000000
Computing gradient descent...
theta_00.0001193267
theta_10.0000000000
Computing gradient descent...
theta_020485726.0000000000
theta_10.0000000000
Computing gradient descent...
theta_0ovf
theta_10.0000000000

etc...
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 19, 2016, 10:56 pm
OK, thanks. I need to include a space in between the theta_0/theta_1 and the numbers. Based on this my learning rate is likely wrong (it needs to not be 0). But it's good that the function works.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 21, 2016, 01:21 pm
I've cleaned up my code a little so that the summations work properly. My output looks like below.

Code: [Select]

Starting...
Computing gradient descent...
theta_0 ovf
theta_1 0.0000000000
Computing gradient descent...
theta_0 nan
theta_1 0.0000000000
Computing gradient descent...
theta_0 nan
theta_1 0.0000000000
...etc


Below is my code.

Code: [Select]

//
// Deep Think 0.0.0.5
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Implement a basic deep learning algorithm (created by the
//    programmer) to choose what course of action to take (a
//    limited number of options).
// 2. Implement a basic system for conversation via the Serial port
//    (this means the robot generates output in response to the
//    user's input).
//
// This version of the program starts dealing with a different
// problem than the previous versions. It handles the
// intelligence aspect of the robot rather than the motors and
// sensors. Later versions will incorporate both once the
// intelligence capabilities have matured. I expect this will be a
// valuable learning process that will help the project succeed in
// the future.
//

//
// Preprocessor Section
//

//
// Let the file be included only once in compilation.
//
#pragma once

//
// Makes sure the appropriate compiler is being used.
//
#ifndef __cplusplus
  #error "A C++ compiler is required."
#endif

//
// Makes sure the appropriate Arduino header is included.
//
#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//
// The other necessary headers are included here.
//

//
// Namespaces
//
using namespace std;

//
// Classes
//

class Node
{
  public:
    //
    // This is to keep track of xi and yi during the summation.
    //
    int col = 0;
   
    //
    // Here is the training set size, which will be used in the calculations.
    //
    int TrainingSetSize = 3;
   
    //
    // Here is the learning rate, which will be adjusted by
    // experimentation until the desired results are achieved.
    //
    float LearningRate = 1;
   
    //
    // Here is the training set to test the algorithm.
    //
    float TrainingSet[2][3] =
    {
      {1.0, 2.0, 3.0}, // row 0 = 1.0, 2.0, 3.0
      {1.0, 2.0, 3.0}  // row 1 = 1.0, 2.0, 3.0
    };
   
    //
    // These variables denote the ith element of x and y
    // respectively in the training set, where x corresponds
    // to row 0 in the training set and y corresponds to row
    // 1 in the training set.
    //
    float xi = TrainingSet[0][col];
    float yi = TrainingSet[1][col];
   
    //
    // These variables are used in the hypothesis function. For this
    // machine learning example h_theta(x) = theta_0 + theta_1 * x.
    //
    float theta_0 = 0;
    float theta_1 = 0;
   
    //
    // Compute the hypothesis function.
    //
    float h_theta(float xi)
    {
      return (theta_0 + theta_1 * xi);
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi)^2, where
    // h_theta(xi) is the hypothesis function of the ith element
    // of x in the training set (xi) and yi is the ith element of
    // y in the training set. This function will be used to
    // compute the cost function.
    //
    float ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += pow(h_theta(xi) - yi, 2);
       
        //
        // Update the column for xi and yi.
        //
        xi = TrainingSet[0][col++];
        yi = TrainingSet[1][col++];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
       
        xi = TrainingSet[0][col];
        yi = TrainingSet[1][col];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the summation of xi * (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += xi * (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
       
        xi = TrainingSet[0][col];
        yi = TrainingSet[1][col];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the cost function.
    //
    float ComputeCostFunction()
    {
      float cost = (1 / (2 * TrainingSetSize)) * ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      return cost;
    }
   
    //
    // Updates theta_0 and theta_1 using gradient descent.
    //
    void UpdateGradientDescent()
    {
      //
      // We can't assign the values directly to theta_0 and theta_1 because they are dependent
      // on each other, therefore the assignment must be simultaneous.
      //
      float new_theta_0 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      float new_theta_1 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(TrainingSetSize);
     
      theta_0 = new_theta_0;
      theta_1 = new_theta_1;
    }
};

//
// Class Objects
//

//
// Create a Node class object here.
//
Node *MyNode;

void setup()
{
  Serial.begin(9600);
 
  while (!Serial)
  {
    ; // wait for Serial port to connect
  }
 
  //
  // Test to make sure Serial is working.
  //
  Serial.println("Starting...");
}

void loop()
{
  Serial.println("Computing gradient descent...");
 
  //
  // Update theta0 and theta1 using gradient descent.
  // ComputeCostFunction is not used here, since the gradient
  // descent algorithm incorporates it (partial derivative
  // of the cost function for j = 0 and j = 1 for theta_j),
  // although it is included since it will likely be used later.
  //
  MyNode->UpdateGradientDescent();
 
  //
  // Print results for observation and analysis.
  //
  Serial.print("theta_0 ");
  delay(1000);
  Serial.println(MyNode->theta_0, DEC);
  delay(1000);
  Serial.print("theta_1 ");
  delay(1000);
  Serial.println(MyNode->theta_1, DEC);
  delay(2000);
}


The interesting thing about the code is that theta_0 outputs characters and theta_1 remains 0 (for this run). Also, when I run the same code more than once it will oftentimes come to different results. What is going on here?? I calculated the math on my calculator, and according to it my implementation is correct. So is there a problem with the Serial?
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on May 28, 2016, 06:20 pm
Just to make sure my algorithm works I'll test it on Octave instead of the Arduino, so I can verify that my implementation is correct. Then I'll post my results here.
Title: Re: Deep Think Project - Artificial Intelligence Research Project
Post by: goodinventor on Jun 27, 2016, 05:58 pm
I'm now beginning to research sensors for use in a basic obstacle detection system, now that I have the servos working and the machine learning research is coming along nicely. I'm thinking of mounting the mechanism in the head (it can be the eyes of the robot). Right now at this moment my biggest problem is keeping the sensitive electronics save. Is there any kind of good quality enclosure that can be mounted vertically that you would recommend? Also, at some point (maybe in a year or so, or less, depending on how progress goes), I am looking into a basic camera system for use with the Arduino.

I was thinking of something like this:

http://www.robotshop.com/en/pixy-cmucam5-image-sensor.html (http://www.robotshop.com/en/pixy-cmucam5-image-sensor.html)

Of course, there are likely plenty of better options, as I haven't done very much research yet (I have learned over time that it is better to spend a lot of time planning rather than diving right into things so that I can get better results). Any advice for working with sensors (particularly vision/obstacle detection related ones) would be greatly appreciated.

Thanks for reading,
goodinventor