iCubSim touching ball on the table
==================================

We control the simulated robot (iCub) via TCP protocol.

0. launch install_and_run.bat, and respond as no to the question about objects.
Python 3.5, 3.6, 3.7, 3.8, 3.9 (the best choice), 3.10, 3.11 are supported.
(In windows 11 you get "Windows protected your PC". Select "More info" and permit
the simulator's exe to run.)

1. Several processes are started:
a) yarp server - a communication tool for iCubSim control
b) iCubSim - simulation of robot iCub in Open Dynamics Engine
c) the motor control GUI from which you can manipulate various degrees 
   of freedom of the simulated iCub robot
d) the ball position GUI from which you can control the position of the ball
   located on the desk in front of the robot 
e) face textures and emotion expression processes - ignore them or cancel

(iCubSim will inform you that e.g.
"You could get a more accurate dynamics simulation by decreasing 
the timestep in ode_params.ini"
just ignore it; one can also change the timestamp in the ini file
but it is not inevitable)

(sometimes the yarp server fails to start, in this case, use or avoid --write in
the iCubSim/run-iCubSim.bat or remove the iCubSim directory)

You can control the viewpoint of the simulation by using the keys:
Q W E R A S D F Z X C V (try)
Key R renews the standard viewpoint.
Please use, e. g., Z W and F to see details on the face of the robot. Then press R.

Please try to set a ball to a particular position and hit it with iCub's hand
via moving individual joints.

Record joint positions for the corresponding ball positions 
(for a few, but not just one ball position)

(The simulator sometimes gets stuck. In this case, close everything and 
start everything again. You can use stop.bat and the install_and_run.bat)

2. TCP protocol is a crucial network protocol that provides 
data stream from one process to another. It was designed 
to provide communication between processes on different nodes in 
a network, but it could also be used as a tool for inter-process
communication on the same node. It is a client-server communication:
one process (client) connects to another listening process (server).
The client needs to specify an address (of a node) and port. The address for
communication on the localhost is 127.0.0.1 or some other virtual
local address (iCubSim employs 192.168.56.1). Port is a number that
enables us to recognize which process the client aims to connect (e.g.
The browser aims to connect to port 80, the number for the webserver).
iCubSim employs ports: 10000, 10001,... (see tcp-iCub.txt)
(Physically, TCP is materialized by a sequence of data packets of 
small and fixed length - IP protocol. In this way, the network can be
shared by many TCP connections).

To try pure TCP communication, launch tcp-server.bat and then 
tcp-client.bat in the telnet directory; by typing in one window, 
you send data to another window. (telnet is pure TCP)
(you can quit the server and client programs via ctrl-c)

Find IP of your classmate by cmd and ipconfig.
Then, modify tcp-client.bat to connect to her TCP server and chat with her.

3. iCubSim can be controlled by yarp application protocol.
(Application protocol is TCP protocol with restrictions on what
characters - and in what order - could be written to the data stream)
to try to communicate with the iCubSim (more precisely with the yarp 
server), launch run-telnet.bat connecting to port 10024 which 
corresponds to the left arm. The port number can be identified
in the console of the iCub_Sim.exe where one needs to look for a line
like 

yarp: Port /icubSim/left_arm/rpc:i active at tcp://158.195.2.6:10024/

it means the telnet needs to connect to the IP address 158.195.2.6 (or 192.168.56.1)
and the port 10024 (see the content of the run-telnet.bat and modify it
accordingly.) (Of course, it is not so easy to search for this information
in the console output; therefore, copy its content via:
the right mouse click on the top frame of the console, edit / select all,
the right mouse click on the selected text, open a new window in the
notepad++ editor, and ctrl-v. Then find the string "/icubSim/left_arm/rpc:i")

When the connection is created, type very carefully (any mistake
namely at the beginning closes the connection) type (confirm each
command by entering):
CONNECT me
response: Welcome me
d
get pos 1
response: position of joint 1
response: [ok] 
d
set pos 1 40
response: robot set joint 1 of its left arm to position 40 degrees
response: [ok] 
d
get pos 1
response: modified position of joint 1
response: [ok] 

Try to launch another client in parallel and set the position of a joint from
one client and get it from the other one
Try to move with the robot head (you need to modify run-telnet.bat file 
according to tcp-iCub.txt again)

(to close a client, press ctrl-c Y enter)

4. python
(for the edition of python programs, use your preferred editor, idle.bat
or Notepad++ but, in the last case, yet apply:
Settings / Preferences / Language / Tab Settings / Replace by space)
(we employ Python 3.7 with preinstalled libraries: numpy, matplotlib, opencv, ...)
We can perform the same job as in 3., i. e., to move with the left hand,
from Python. Launch run-noyarp.bat,
which first finds the port (which we entered manually in 3.)
by calling yarp naming service on port 10000.
It is not inevitable to understand everything in the code noyarp.py, 
but please try to find where the "d" command is added to the front of the message
you enter as the second argument of the batch file run-noyarp.bat
Launch cmd in your working directory (in any way you know or by run-cmd.bat)
and mimic command from the batch file (then use arrow-up to repeat and
rewrite the command) and move somehow with the robot head

Launch renew.bat to renew the standard position of the robot joints.

5. programming
Ok, we can control the robot by calling python program.
Let us go to write our program in Python.
Use the prepared program myprogram.py, which can be launched by run-myprogram.bat
Modify the program to control iCub hand to hit the ball in the given position. 
(Suppose that the entered position corresponds to the value set by BallControll).
(In this way, you implement inverse kinematics)
(use the MotorControlGui to find the suitable constants)
