Page 1 of 2
Limited capabilities of NXC
Posted: 26 Oct 2010, 17:04
by kizzard
I just got an NXT recently and have just started programming in NXC.
In the process of trying to code a queue to queue instructions that will be sent to the robot, I've run across some rather glaring limits on what can be expressed with this language.
No pointers, and no arrays in structs are the first things that hit me.
I did expect some incompatibilities with regular c, but not quite this.
Can anyone suggest if LeJOS allows more complex code than this? And does it allow for object oriented code too?
Is the JVM that LeJOS implements a faithful representation of the real thing, or is a limited "not quite java" deal like NXC is?
Thanks
(please note it is not my intention to insult the NXC developers! It is just not quite what I was expecting.)
Re: Limited capabilities of NXC
Posted: 26 Oct 2010, 18:02
by mightor
Well, NXC is Not eXactly C
I guess it's Not eXacty What You Were Looking For.
Lejos is proper Java with a beautiful and very rich class library. It is limited in terms of memory and that kind of thing. If you are looking for ANSI C, you should check out something like nxtOSEK or NXOS, it uses GCC.
- Xander
Re: Limited capabilities of NXC
Posted: 26 Oct 2010, 18:28
by kizzard
Ah, thank you! Perfect answer.
I am simply after a compiler/firmware with a rich language. Those sound great. Memory is not an issue for me as the planning/AI/number crunching will be done on my computer. All I need the onboard controller to do is carry out commands sent to it and feed back translated sensor readings.
Again no offense intended to John Hansen and other devs (and my thanks for giving us an otherwise great compiler)
Re: Limited capabilities of NXC
Posted: 26 Oct 2010, 19:11
by gloomyandy
Just to provide a little more detail. leJOS provides pretty much all of the language features of Java. About the only things missing are the ability to dynamically load classes and introspection. You get all of the data types (including things like enums), plus all of the threading, exceptions etc and a pretty good gc. For development you can use normal tools like Eclipse or NetBeans. The class library is pretty good, however it does not include a full set of JavaSE classes, but most things are there. The class library also includes a lot of NXT specific features so classes for sensors, sound, motors, i2c, rs485, USB, Bluetooth etc.Plus a pretty comprehensive set of robotics specific classes that can be used to control a robot, implement subsumption etc... Many of the same classes can also be used for PC side programming (using a sort of remote execution), there is also a PC side library that provides classes to access the NXT via i/o streams over both USB and Bluetooth. Probably the weakest area with the current system is the lack of debug facilities. The best we can offer at the moment is the ability to use println style debugging via a remote console that operates over USB/BT. You can take a look at the current release API here:
http://lejos.sourceforge.net/nxt/nxj/api/index.html
Andy
Re: Limited capabilities of NXC
Posted: 26 Oct 2010, 23:14
by kizzard
Thanks for the information, Andy. I got LeJOS a couple of hours ago and have written have a functioning onboard controller. I am impressed, LeJOS is excellent, just what I was after!
Re: Limited capabilities of NXC
Posted: 27 Oct 2010, 00:47
by cghaning
kizzard wrote:... no arrays in structs are the first things that hit me.
Unless I've written an example that somehow works and shouldn't, I don't believe this is true any longer. I am using BricxCC Version 3.3.8 and enhanced firmware 1.28.
This example program will write the results to a csv file so you can see what is going on.
Code: Select all
#define DEBUG_Q 1
struct Qdata
{
long x,y,z;
};
#define QTYPE Qdata
int handle; // File for testing
int tmp_cnt;
string tmp_str;
struct Q_t
{
u8 size;
u8 num;
u8 wpos;
u8 rpos;
QTYPE data[];
};
void InitQueueM(const u8 &Size, Q_t &this)
{
this.size = Size;
QTYPE zero;
ArrayInit(this.data,zero,Size);
#if DEBUG_Q
// Write out column headings
tmp_str = FormatNum("InitQueue of size %d",this.size);
WriteLnString(handle,tmp_str,tmp_cnt);
tmp_str = "Command,Value,";
for(int st=0;st<Size;st++)
{
tmp_str += FormatNum("Index %d,",st);
}
tmp_str += "Write Index,Read Index,Number of Entries";
WriteLnString(handle,tmp_str,tmp_cnt);
#endif
}
u8 push(const QTYPE &z, Q_t &this)
{
//Returns number of entries, Zero on failure
// copy out struct members
u8 tmp_num = this.num;
u8 tmp_wpos = this.wpos;
u8 tmp_size = this.size;
if (tmp_num >= tmp_size)
{
#if DEBUG_Q
WriteLnString(handle,"QUEUE FULL",tmp_cnt);
#endif
return 0;
}
this.data[tmp_wpos]= z;
++tmp_wpos;
if (tmp_wpos >= tmp_size) tmp_wpos = 0;
++tmp_num;
// copy back to struct
this.num = tmp_num;
this.wpos = tmp_wpos;
#if DEBUG_Q
// Write out value to file for testing
tmp_str = FormatNum("push,%2d-",z.x);
tmp_str += FormatNum("%2d-",z.y);
tmp_str += FormatNum("%2d,",z.z);
for(int d=0;d<this.size;d++)
{
tmp_str+=FormatNum("%2d-",this.data[d].x);
tmp_str+=FormatNum("%2d-",this.data[d].y);
tmp_str+=FormatNum("%2d,",this.data[d].z);
};
tmp_str += FormatNum("%2d,",this.wpos);
tmp_str += FormatNum("%2d,",this.rpos);
tmp_str += FormatNum("%2d,",this.num);
WriteLnString(handle,tmp_str,tmp_cnt);
// END Write out value to file for testing
#endif
return tmp_num;
}
u8 peek(QTYPE &z, Q_t &this)
{
//Function returns number of entries
// if zero, z is undefined
z = this.data[this.rpos];
return this.num;
}
u8 pop(QTYPE &z, Q_t &this)
{
//Return number of entries before pop
//if zero queue was empty
u8 ret = this.num;
// copy data out of struct
u8 tmp_num = ret;
u8 tmp_rpos = this.rpos;
u8 tmp_size = this.size;
if(ret <> 0)
{
z = this.data[tmp_rpos];
QTYPE zero;
this.data[tmp_rpos] = zero;
++tmp_rpos;
if(tmp_rpos >= tmp_size) tmp_rpos = 0;
--tmp_num;
}else
{
#if DEBUG_Q
WriteLnString(handle,"QUEUE EMPTY",tmp_cnt);
#endif
return ret;
}
// copy back to struct
this.num = tmp_num;
this.rpos = tmp_rpos;
#if DEBUG_Q
// Write out value to file for testing
tmp_str = FormatNum("pop,%2d-",z.x);
tmp_str += FormatNum("%2d-",z.y);
tmp_str += FormatNum("%2d,",z.z);
for(int d=0;d<this.size;d++)
{
tmp_str+=FormatNum("%2d-",this.data[d].x);
tmp_str+=FormatNum("%2d-",this.data[d].y);
tmp_str+=FormatNum("%2d,",this.data[d].z);
};
tmp_str += FormatNum("%2d,",this.wpos);
tmp_str += FormatNum("%2d,",this.rpos);
tmp_str += FormatNum("%2d,",this.num);
WriteLnString(handle,tmp_str,tmp_cnt);
// END Write out value to file for testing
#endif
return ret;
}
task main()
{
QTYPE tmp;
DeleteFile("qstruct.csv");
CreateFile("qstruct.csv", 8192, handle);
Q_t myQ;
InitQueueM(5,myQ);
tmp.x = 100;
tmp.y = 55;
tmp.z = 33;
push(tmp,myQ);
tmp.x = 99;
tmp.y = 54;
tmp.z = 32;
push(tmp,myQ);
pop(tmp,myQ);
pop(tmp,myQ);
}
Re: Limited capabilities of NXC
Posted: 27 Oct 2010, 04:07
by afanofosc
Definitely no pointers in NXC since the underlying VM doesn't support any kind of indirect memory access (until recent enhanced NBC/NXC firmware changes) But you've had the ability to use arrays in structures for about as long as NXC has existed. You just can't define the array size statically due to the way the underlying VM implements the executable file format and the dataspace of each program. You have to specify the size of a struct member that is an array for each instance of the structure type. The compiler could do this magically for you and I may add that feature in the future.
I highly recommend leJOS or pbLua as great alternate firmware options for programming the NXT. If you want to more easily switch between NXT-G and a text-based programming language then NXC may be better since it supports the same VM as NXT-G.
John Hansen
Re: Limited capabilities of NXC
Posted: 27 Oct 2010, 04:33
by kizzard
Thanks for clearing that up John. By the way, I bought your book and found it very helpful! Thanks.
Re: Limited capabilities of NXC
Posted: 27 Oct 2010, 12:54
by HaWe
what would be great: if someone could change the "clump" method for storing values to a stack / heap design (using the gcc compilated fw)
Then we might have recursion, pointers, dynamic memory allocation,.... *sigh*
Re: Limited capabilities of NXC
Posted: 28 Oct 2010, 01:45
by muntoo
doc-helmut wrote:what would be great: if someone could change the "clump" method for storing values to a stack / heap design (using the gcc compilated fw)
Then we might have recursion, pointers, dynamic memory allocation,.... *sigh*
I feel your pain.
Real pointers* would be awesome; better than recursion, IMHO.
* not the addressOfEx(), or IOMapReadByID(), etc; but this:
Code: Select all
int* x=&y;
*x=5;
// Now to corrupt some memory, just for kicks ;)
x=0xAAAA
*x=1234