Deep Think Project - Artificial Intelligence Research Project

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.

//
// 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

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.

//
// 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

although the code compiles fine

No it doesn't.

 // set up DC motors
  pinMode(

Pete

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.

Here is the fixed code. Can you find any other issues?

//
// 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);
}

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

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. Meccano

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.

goodinventor:
Here is the fixed code. Can you find any other issues?

//

// 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.

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.

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.

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.

goodinventor:
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.

goodinventor:
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/

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?

goodinventor:
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.

Yes, I know. It can be used to describe dividing the load across multiple cores or multiple processors.

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 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.

goodinventor:
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.

Here is the lesson at the address above, with code development and all the whys

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.

goodinventor:
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 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.

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?