Wishlist for C for EV3 (EVC, EV3-C)

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

hey to all,
and especially of course: hey John! :P

The cards have to be shuffled - so new game, new luck! :mrgreen:

In order not to fall into the same traps as by NXC, I would venture to propose the following new features for a new API:

Sensors:

Currently it's very complicated if not impossible to make different sensor settings or to get different sensor readings at different ports in a loop or to pass them to a function or to get sensor values returned by a remote function.
So my suggestion is to revive the ancient syntax of NQC and initial NXC providing a SetSensor(......) and a GetSensor(......) function.

My proposal:

Code: Select all

SetSensor(char port, long SensorType)
SensorTypes coud be defined in a sensor header like

#define SENSOR_LEGO_TOUCH 1
#define SENSOR_LEGO_TOUCH_EDGE 2
#define SENSOR_LEGO_TOUCH_PULSE 3
#define SENSOR_ADC_RAW 10
#define SENSOR_LEGO_LIGHT10_PASSIVE 20
#define SENSOR_LEGO_LIGHT10_ACTIVE 21
#define SENSOR_LEGO_COLOR20_FULL 110
...
#define SENSOR_I2C_LEGO 1009 // Lego standard 9k
#define SENSOR_I2C_100k 1100 // i2c std 100k if possible by hardware
...
#define SENSOR_RS485 2000
...
and so on.

To poll all the sensor values in a similar systematic and logical way, both for single values and for arrays like color sensors or 3D accelerometers, I would appreciate the following way:

Code: Select all

GetSensor(char port, long SensorType, long & values[]) // (in plain C: the pointer to the array)
Having this syntax, you are able to poll both the single value of a touch sensor and the sensor array of 3 dim accelerometers or 9 dim IMU sernsors by the same kind of function call.

ps:
again thinking about the implementation:
when passing the sensor types/modes to the GetSensor function, one may even drop the SetSensor initializing completely because then initializing is implicite.
Otherwise, using SetSensor() then one could drop the sensor types in the GetSensor function.

(to be continued)
Last edited by HaWe on 11 Aug 2013, 12:10, edited 4 times in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

Remote Control (Direct commands)

the analogical syntax could be used for direct commands without having to use mailboxes or to establish permanent send/receive loops running on any EV3 brick:

Code: Select all

RemoteSetSensor(char conntype, long netID, char port, long SensorType);  
RemoteGetSensor(char conntype, long netID, char port, long SensorType, long & values[] );   
RemoteGetEncoderCounter(char conntype, long netID, char port, long & values[]);

Code: Select all

RemoteSetSensor(USB, 4, S1, SENSOR_LEGO_TOUCH);  // via USB: config at EV3 #4: Touch sensor at S1
RemoteSetSensor(USB, 3, S2, SENSOR_LEGO_USNXT);  // via USB: config at EV3 #3: US sensor at S2
RemoteSetSensor(USB, 2, S3, SENSOR_ADC_RAW);     // via USB: config at EV3 #2: analog sensor (ADC raw) at S3

RemoteGetSensor(USB, 4, S1, SENSOR_LEGO_TOUCH, long & values[] );      // via USB: read at EV3 #4: Touch Sensor value at S1
RemoteGetSensor(USB, 3, S2, SENSOR_LEGO_USNXT, long & values[]);       // via USB: read at EV3 #3: US Sensor value at S2
RemoteGetSensor(USB, 2, S3, SENSOR_ADC_RAW, long & values[]);          // via USB: read at EV3 #2: analog sensor value (ADC raw) at S3

RemoteGetEncoderCounter(USB, 4, OUT_C, long & EncoderCounter[]);    // via USB: at EV3 #4: read motor rotation counter of OUT_C (e.g., OUT_BC optional)
An underlying network protocoll should make it MT-safe and should protect from data collision, data loss, and data corruption.

for using BT instead of USB, just the data transmission mode might have to be exchanged:

Code: Select all

RemoteGetSensor(BT, 4, S1, SENSOR_LEGO_TOUCH, long & values[] );      // via BT: read at EV3 #4: Touch Sensor value at S1
RemoteGetSensor(BT, 3, S2, SENSOR_LEGO_USNXT, long & values[]);       // via BT: read at EV3 #3: US Sensor value at S2
RemoteGetSensor(BT, 2, S3, SENSOR_ADC_RAW, long & values[]);          // via BT: read at EV3 #2: analog sensor value (ADC raw) at S3


(to be continued)
Last edited by HaWe on 23 Jun 2013, 07:55, edited 1 time in total.
markcrosbie
Posts: 34
Joined: 30 Sep 2010, 09:56
Location: Ireland
Contact:

Re: Wishlist for C for EV3

Post by markcrosbie »

doc-helmut, have you perhaps thought of moving to leJOS for what you are trying to achieve? It supports callbacks for sensor monitoring so you never poll a sensor - you merely register a class that implements an interface and it gets called whenever a sensor changes.

http://lejos.sourceforge.net/nxt/nxj/ap ... tener.html
and
http://lejos.sourceforge.net/nxt/nxj/ap ... rPort.html

Just a thought...
Mark
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

as it's off-topic in this thread...
I naturally thought of the idea already (and even tried it out) but dismissed it since the times of the RCX -
as it turned out since that time that I really hate classes and objects and heredity, extensions, instances, interfaces, install-, and include- and where or to-what ever paths ( and all of their modifications and adjustments which have to be considered or be made) like the PLAGUE ! :twisted:

Already at the thought of "programs" in Java being named "classes", my brain ties into knots. Image

And I'm always thinking and acting and programming procedural, not objectural.

If I want to switch a lamp on or off or I want my robot to screw a bulb into the thread, I write procedures for the lamp or for the motors at my robot motor ports to do this
(e.g., OnFwd(port,...) ).
What I don't need is an army of robot classes, objects, implementations, instances, and extensions and implementations, objects, methods and instances of bulb classes, to do sth weird like

Code: Select all

bulb.this.shine_light
bulb.this.extinguish_light
bulb.this.screw_into_thread
not to forget first to try and then to throw exceptions above and behind and beyond. Image

But moreover: I'd love to have an ANSI C compiler generating insanely fast genuine ARM machine code instead of a comparatively lame bytecode interpreter :ugeek:
As I got about 5000-10000 changing sensor values each and every second which have to be processed and calculated, e.g., by PID controllers, Kalman and Monte Carlo filters, Fourier transformation, neural nets, odometric and astar and bug2 navigation and localization procedures, there is no need for sort of a sensor-event-watcher which tells when a single value had changed;
but instead, a couple of µCs are needed which are communicating with each other and which have got inputs for all over 10-12 encoder motors and a few dozens of sensors, and which are able to handle and process and calculate all the incoming values extremely quick in real-time.


But this issue is really more than off-topic here in this thread and so it should not be further discussed here. :?

After all, anyway, thank you for your hint - my abysmal, profound aversion to Java should be in no way an offense to you 8-)
Last edited by HaWe on 23 Jun 2013, 07:55, edited 1 time in total.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

screen <=> stdout: printf, printfxy

if there shouldn't already exist a stdio.h library coming with the ARM C compiler:

Wishfull is a printf() which writes to the screen (stdout device), featuring linefeed ("\n") for the format strings and automatic wrap at end of a line and scrolling the screen.

Code: Select all

int printf ( string format, variant value);
// in plain C:
int printf ( const char * format, const variant * value, ... );
Additionally a printfxy would be nice writing like printf but starting at a certain screen position:

Code: Select all

int printfxy (int x, int y, string format, variant value, ...);
// in plain C:
int printfxy (int x, int y,  const char * format, const variant * value,... );
alternatively for cursor positioning, we also might have a

Code: Select all

gotoxy  (int x, int y); 
// plus a  following
int printf ( const char * format, const variant * value, ... ); 
for graphic screens, usually (0,0) is the most upper left postion of the screen;
for compatibility reasons, it should be considered to apply this setting, too.


both printf and printfxy should be able to get variables and expressions passed to (like e.g., functions)

all print-like functions should support function overloading to be able to pass multiple format strings and multiple variants, e.g. like

Code: Select all

printf ("Some different radices: \n%d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
printf ("%2d ply, %9d searched, %6d by (%2x,%2x)\n",d-1,N,m,X,Y&0x77);
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

Motor Control

the current NXC motor control function are partially uncomfortable and dysfunctional as they are based upon a (IMO) rather weird Lego firmware.

As we now will have a new firmware, the motor control functions should be revised to a more logical and more comfortable syntax and functionality.

The old NXT-Lego-FW based functions should not be necessarily provided any more, e.g., there is also no need to switch 2 or 3 or 4 motors all at once by 1 command, that simplifies the command structure respectively related to remote motors of daisy-chained EV3s).
As another example, there is no need to support the NXC-FW motor-output and motor-regulation fields any longer, and for approaching an absolute motor encoder target there should be API funtions of a completely different design.

Motor on / break / coast:

Code: Select all

OnMotor(output, pwr);
Brake(output);
Coast(output);
relative rotation:

Code: Select all

RotateMotorDegrees(output, degrees, pwr)
RotateMotorDegrees(OUT_A, 3600,   80) 
Sync control: For the Synced mode it just has to be defined which is the master and which is the slave; the first which is listed should be the master, the 2nd to be slave.
All pwr or angle values passed to function are related to the master.
The Sync Ratio is based upon the percentual ratio to the master's rotation speed, e.g. 100% means equal rotation speed, 50% ==half, 0 == no slave rotation, -60%== 6/10 speed and negative direction)

Code: Select all

OnMotorSync(master_out, slave_out, master_pwr, sync_ratio)
OnMotorSync(OUT_A, OUT_D, 80, -60)
In combination to a relative encoder target value the sync function (if provided) lets the slave approximate it's target by the fraction of the masters' rotation target. E.g.:
relative rotation target of the master: 3600
sync ratio: 50
=> synchronized rotation counts of the slave (calculated automatically): = 1800,
slave speed adjusted to the current master rotations to keep both motors synchronized in progress,
if slave is stalling, then the slave pwm power has to be increased and the master has to be slowed down.

Code: Select all

RotateMotorSyncDegrees(master_out, slave_out, master_rot_count, master_pwr, sync_ratio)
RotateMotorSyncDegrees(OUT_A, OUT_D, 3600,   80, 50) 
PID control for rotation counts:
additionally p,i,d passed to the function (float values without restrictions to multiples of 32, 1, or whatever)


Absolute target approximation should be provided by functions like

Code: Select all

SetMotorTarget(output, target)
RotateToEncoderTarget(output, pwr, stop_mode) // automatic stop_mode= CONTINUE or BRAKE or COAST
Runstate(output) // IDLE  or BUSY or RAMPUP or RAMPDOWN or HOLD 

// stopping motors or interrupting any current motor control by:
Brake(output)
Coast(output)
PID control for target approximation:
additionally p,i,d passed to the function

All motor controlling will have to run in seperate tasks without any mutexes, in order to be possibly changed or interrupted at any time and to allow other motor tasks to be additionally started or stopped in between times.

As an enhancement, for PID control also other sensor inputs might be defined different from rotation counts, e.g., US Sensor values.
By this, the motors can be commanded to run until the sensor value has been reached and/or keep the distance in continuous mode (e.g., a distance of 50 (cm) given by the US sensor).

For this it should be possible to pass a function as a parameter to this PID control procedure:

Code: Select all

SetPIDReferenceInput(port, sensorfunction() )
SetPIDReferenceInput(OUT_A, RotationCount(OUT_A) ) // default
SetPIDReferenceInput(OUT_A, GetSensor (USSensor, S3) )  // customized
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

ANSI-C (e.g., C99) compatibility for EV3-C for the bytecode interpreter (aka EVC) :


of course it would be nice if we finally also had at least ANSI-C99 compatibility, e.g. pointers, recursions, and dynamic memory allocation and furthermore prototypes and function overloading as with C++ plus a <stdio.h> also for C for the Lego virtual machine (aka EVC).

(already been a long-cherished desire for NXC and the NXT: "A Kingdom of Heaven if NXC had (pointers and) recursions")

I also would appreciate if we had DOUBLE as a data type.

http://sourceforge.net/apps/phpbb/mindb ... &t=26#p157

:)
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by mightor »

Recursion, I am not sure the VM currently supports this and was not really designed with this in mind. Adding support for it would mean a (partial) rewrite.
All the things you want could be achieved with a standard C based library, which John and I are working on. You'd use Eclipse (or perhaps BrixCC, should John decide to add support for gcc) to compile Linux ELF binaries, which you would transfer to the EV3 brick over either WiFi, BT or USB. Multitasking would be a bit more cumbersome but there are lots of really nice frameworks out there that would allow you to achieve proper multitasking.
Dynamic memory allocation is supported in the VM but I am not sure it can be accessed directly but there are ways to grow arrays, etc, which is probably what you'd want for your neural networks. I have no indications on how fast the array stuff in in the VM, I have not tested this.

Regards,
Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

I didn't ever use this monster Eclipse (I actually once tried but then resigned immediately) and I never compiled anything but comparatively simple Borland C++ programs for Windows and devcpp C programs for a command console, and I never ever used LINUX, so I don't know anything about cpp or Linux ELF (?).

For recursions, partial rewrite of the original fw for the bytecode interpreter is maybe not neccessarily an obstacle but IMO worthwhile though.

- Recursions are need for AI game engine deepenings (Towers of Hanoi and alpha-beta-search for chess and draughts,... ) and for matrix algebra (e.g., recursively calculating transposed and inverted more-dimensional matrices)

- dynamic memory allocation particularly is for map and explore robots and astar node expansions (they all need temporarily big (a 100x100 plus several 100x2) arrays of int), and for different dynamic linked lists of variable sizes generated at run-time,

- Preemptive multitasking is absolutely indispensable for anything and everything (at best - but not necessarily - featuring real-time task control like nxtOSEK) ,

- EV3 daisy chaining via USB is absolutely indispensable to be able to plug up to 1 dozen of encoder motors and several dozens of sensors (like for my Johnny5-like map-and-explore 7-8 DOF service robot ^^ ),
for multi-core-processing of computationally intensive calculations, like for multi-cube-(4x, 5x, 7x) solvers and for powerful high-level-deepenings for my chess engine,
and for passing large map arrays and intermediate calculation results for navigation, localization, and bearing.

Having these features for the EV3 it would be really worth-while to buy a couple of them, because then with the EV3 one would really have a much greater benefit than currently with the NXT, already when using bytecode interpreters :geek: -
phenomenal and incredible if we had it for machine code executables :ugeek:
- but compiling and uploading to the brick should be as easy as for VM files by BCC :idea:
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Wishlist for C for EV3 (EVC, EV3-C)

Post by HaWe »

Remote Control (2) (Send and receive values of different data types)

the analogical syntax like for direct commands could be used for variant data transmission without having to use mailboxes or to establish permanent send/receive loops running on any EV3 brick:

Code: Select all

RemoteSendValue(char conntype, long netID, int VariantID, int NumberOfBytes, const variant  * msg );
RemoteReadValue(char conntype, long netID, int VariantID, int NumberOfBytes, variant * msg ); 
 
msg might be a simple data type like char, int, long, float, double, string
an array of those simple data types, (like, e.g., int board[129] )
a more-dimensional array of one of these data types (like, e.g., char map[100][100] )
or a composed data type like a structure.

The API function is expected to automatically transform the variant data into an array of byte (sort of automatic FLATTEN) , transmit it, and re-tranform it to the original data type (sort of UNFLATTEN).
Long messages up to max short_int bytes
char msg[32767]
should be able to be transmitted, and (if needed) automatically splitted and rearranged again .
Last edited by HaWe on 16 Aug 2013, 08:29, edited 1 time in total.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest