Coulomb’s Law Simulation

Posted in Uncategorized on March 18th, 2010 by Chaos Engineer

I created a gravitational simulation a while back, and it was pretty cool. I was recently reading an article about how similar Coulomb's Law is to Newton's Law of Universal Gravitation. I thought I would visit the world of physical simulations again, this time using my strange attractor engine to simulate charges in an electric field.

Obviously the first step is to create charges that contribute to an electric field. The simple solution is to turn the points on the attractor into electric charges, lets say electrons. We now have a collection of charges creating an electric field. The next step is to implement Coulomb's Law.

The scalar form of Coulomb's Law states that f = k * ( (q0 * q1) / (r * r) ), where k is the Coulomb constant, q0 is the charge of particle 1, q1 is the charge of particle 2, and r is the distance between the particles.

There are a couple things to note about this equation. Most importantly is how the sign of the charge on each particle effects the sign of the force magnitude itself. Two charges of like sign result in a positive force, and two charges of opposing sign result in a negative force. Also, this equation simply gives the magnitude of the force, there is no direction associated with it.

To get a resultant force vector is quite simple. We take the vector formed by the two particles, and reduce it to unit length. We then multiply this unit length vector by the scalar magnitude of the force as determined by Coulomb's law.

To create a "field", we have to find the cumulative force felt on a charge from all sources. So to put it in programmer language, for each individual particle we iterate through all the charged particles in range, accumulating the force vector for each to create a resultant overall force vector. It can be said that this resultant force vector represents the field at that given point.

Obviously we can then resolve this force into acceleration knowing the particle's mass. Maintaining a velocity vector for each particle, we can use this acceleration to create a realtime simulation of the particle's motion through the field. As the position of these particles change, the field changes, creating a feedback system. Any lover of chaos knows we have established the prime requisite for a complex system. Hopefully we can stir some emergence from this system.

Applying these rules to a simple collection of electrons isn't very interesting. The cloud of electrons just explodes outward, and continues on to infinity (assuming no dampening). We need to add some positive charges to the mix, and shake it about. For the interest of science, let us create atomic nuclei with a charge much greater than that of a single electron.

Throwing a couple of randomly positioned positively charged nuclei into the simulation does indeed spice things up. Now we get quite interesting swirling clusters of electrons, some maintaining orbits strongly resembling electrons in the common depiction of the atom.

Sometimes an electron will approach a nucleus on just the right vector and get very very close to it's true position. This causes the denominator of the Coulomb's Law equation to approach zero, and the magnitude of the force to skyrocket. This results in the electron being flung off into space at high speeds. I wanted to address this problem, as it didn't jive with the aesthetics I hoped for.

I remember watching an episode of Fringe not too long ago, where two people were discussing the collision of two dimensions. One of the individuals dropped a reference to the Pauli Exclusion Principle, and then smashed two snowglobes together for effect. This principle explains much about the structure of atoms, and applies here because of what it says about electrons orbiting the atomic nucleus. Exercising some artistic liberties with the interpretation of this principle, I made our nuclei exert an exponentially increasing opposing force on electrons that approached too closely. If you wanted to add some scientific rigor, it would be elementary to make definitions on the characteristics of each nucleus, and apply a different force gradient to approaching electrons based on how many were already in orbit. You could easily create electron shells where the outermost (valence) shell could contain electrons that could easily be pulled off by passing nuclei, just like in chemical reactions!

I didn't go so far as to create multiple shells (yet), but the initial results are promising. The electrons around the nucleus form self-organizing spheres, as they seek the lowest energy by spacing themselves evenly across the surface. When multiple nuclei are interacting, its neat to see how the charge density changes and the electrons pack themselves more densely on the sides of the sphere facing nearby nuclei.

I'm looking forward to modulating the charge of nuclei based on realtime audio FFT data.

NDS WiFi Programming with devkitARM — Part 4

Posted in NintendoDS, Uncategorized, sensors on February 25th, 2010 by Chaos Engineer

We've established the important parts of the PC application, the NdsInterfaceHost, and now comes time to actually delve into the DS programming aspects w/ devkitARM and dswifi. We will here lay out the design of the NintendoDS application, the NdsInterfaceClient. Many of the network and socket concepts we covered during Part 3 of this article will carry over into the DS code. I will try not to cover the same ground. Also note that it is entirely possible to use C++ and iostream type code with devkitARM. I chose to use standard C because it is less verbose, and for the DS platform, it just seems more appropriate to use less abstraction.

The NDS application exhibits much code that is ancillary to the main purpose of the project. Being a platform that is rarely developed for, there is only a small community focusing on NintendoDS development. I figure that any code that exploits the features of the DS or establishes a framework that can be extended and used for new purposes is a good contribution to the community. I won't cover this ancillary code, but be sure to download the project and examine the extra bits like the chat server that will let you telnet into your DS.

The basis of the NdsInterfaceClient is simple. On start, it displays some information about the DS it is running on, and then prompts the user to press B to get a list of wireless access points (APs). The code then calls Wifi_ScanMode(), and enters a loop that constantly polls the number of APs, collects information about each, and displays this information on the screen. The Wifi_ScanMode() call actually tells the dswifi library to poll and maintain an internal list of available APs. You can then query the length of this internal list using Wifi_GetNumAp(), and then get specifics using Wifi_GetAPData(...), passing the index of a particular AP.

For the AP list, I reused some code written by Stephen Stair (the author of the dswifi library). I added some ANSI color for readability, and changed the format for AP data so it offered more info, particularly letting the user know if an AP was WAP protected (and thus unusable by dswifi). One of devkitPro's first feats was to implement a console on the DS. The state of this implementation today is quite elite. The console supports ANSI escape sequences, which allow coloring text and arbitrarily relocating the cursor position. One could create an ASCII game using the console and escape sequences alone. The chat server code shows how to use escape sequences to create a "window" in the console.

Once an AP is selected from the list, the code will determine if the user needs to enter an encryption key. If so, a keyboard appears, and allows the entry of an encryption key. The user can enter either a 40b or 104b encryption key. Based on the length of the entry, the code determines if it is 64 or 128-bit WEP encryption, and attempts a connection to the AP. This is one of the least documented basic steps for using dswifi, and on top of that, there are some curiosities worth mentioning.

WAP encryption is unsupported by the NDS and NDS Lite. Support for WAP was added to the DSi, but it isn't likely we'll see it supported by the dswifi library any time soon, if ever. We are limited to using WEP-secured APs. There are two levels of supported WEP encryption, 64-bit and 128-bit. Here is where a curiosity appears. Both 64b and 128b WEP encryption use a 24b Initialization Vector, which is not included in the length of the encryption key you enter. So the actual length of the entered encryption keys for 64b and 128b WEP encryption are 40b and 104b, respectively. It is fine to refer to these encryption levels as either bit length including the IV, or bit length excluding the IV. Strangely, the dswifi library does both, and defines the following two values: WEPMODE_40BIT and WEPMODE_128BIT. It should be obvious which is which.

So, with the keyboard displayed a user can enter the ASCII representation of a 40b or 104b hex key, which is either a 10 or 26 character long string, respectively. We then need to convert this ASCII representation of a hex value into a 5 or 13 byte actual hex value. To accomplish this, we look at each character in the string and convert it from it's ASCII value to it's hex value. We then pack two of these hex values into a single byte (unsigned char), and append each byte onto our encryption key. Once we have 5 or 13 of these bytes, we pass them to the Wifi_ConnectAP(...) function, and wait for the connection to succeed or fail. This is accomplished by polling Wifi_AssocStatus(), waiting for it to return ASSOCSTATUS_ASSOCIATED, or ASSOCSTATUS_CANNOTCONNECT.

Once we successfully connect to a wireless access point, our DS will be assigned an IP address (we assume the use of DHCP). Now connected to the network, we can then start using functions like gethostbyname(...) to look up DNS entries, or connect(...) to make socket connections to remote hosts. Things are finally getting interesting. To provide a user interface to a variety of functions, we print a simple menu, with each DS button bound to a different function, and wait for a keypress:

 
if(status == ASSOCSTATUS_ASSOCIATED) while(1)
{
	u32 ip = Wifi_GetIP();
 
	consoleClear();
 
	iprintf("\n");
	iprintf("ip: [%i.%i.%i.%i]\n", (ip ) & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF);
	iprintf("--------------------------------\n");
	iprintf("Press Y to nslookup host name\n");
	iprintf("Press X to connect to interface\n");
	iprintf("Press A to listen on socket\n");
	iprintf("Press B to break\n\n");
 
	keypressed = 0;
	while(!(keypressed & (KEY_Y | KEY_X | KEY_A | KEY_B | KEY_L)))
	{
		scanKeys();
		keypressed = keysDown();
	}
 
	if(keypressed & KEY_Y)
	{
		//execute gethostbyname(...)
	}
 
	//etc...
}
 

Now the code governing the interaction with the Host interface is very similar to the code in the NdsHostInterface application. We synchronously send a register signal, receive the signal port (and data port) back with the register acknowledgement signal from the Host interface. We then use this signal port to construct a listener, and this data port to pipe input data to the Host. This is the main loop of the NdsInterfaceClient:

 
while(1)
{
	tvTimeout.tv_sec = 0;
	tvTimeout.tv_usec = 1000; // This will throttle the data xfer rate just a tad...
	// I've found that anything less than 1000 microseconds will make select return immediately
	// when called on the DS platform
 
	FD_ZERO(&fdsRead);
	FD_SET(sktServer, &fdsRead);
 
	retval = select(1, &fdsRead, NULL, NULL, &tvTimeout);
 
	if (retval == -1)
		iprintf("select() error\n");
	else if (retval)
	{
 
		if((sktClient = accept(sktServer, (struct sockaddr *)&adrSignalClient, &iClientSize)) < 0)
		{
			iprintf("Failed to accept client connection.\n");
			continue;
		}
		iprintf("Client connected: %s\n", inet_ntoa(adrSignalClient.sin_addr));
		InterfaceSignalHandler(sktClient);
	}
 
	// If there are no signals from the host, and pen is down, send input data on UDP port.
	if(keysHeld() & KEY_TOUCH)
	{
		touchRead(&touchXY);
		pos = 0x00000000;
		pos = (touchXY.px | ((int)(touchXY.py) << 16));
		iprintf("Sending 0x%x", pos);
		sendto(sktData, &pos, 4, 0, &adrData, sizeof(adrData));
	}
 
	scanKeys();
	if(keysDown() & KEY_B)
		break;
}
 
// Broke out of main loop, so unregister from Host and shutdown...
 

That is really the jist of the NdsInterfaceClient. Obviously check out the source code to see how to appropriately construct sockets. In my last article in this series, I'll provide links to the complete source code for both applications. I might take the time to make the NdsInterfaceHost compile on Windows as well as Linux and OSX, but no promises. I'd rather leave the standard Berkeley sockets implementation alone, and let you port it to winsock yourself... or even better let you install a REAL operating system, and run it there. =)

DERAILED — Platform independent dynamic linking

Posted in Uncategorized on August 9th, 2009 by Chaos Engineer

Ooops, I definitely got sidetracked more mucking around with my platform independent rendering engine. Instead of just holding out on the NDS wifi article in silence for any longer, I thought I would chime in and let you know I haven't forgot about you and show you what I've been up to.

My platform independent rendering engine is based on a pure virtual renderer base class that is filled with an instance of a derived class by a dynamically linked code module. Along with the pure virtual renderer class, there are a few pure virtual resource classes as well, the actual instantiation of which are performed by the renderer class. Trying to maintain platform independence, the singleton (factory / manager) class that returns this renderer instance has some interesting code I thought I would share.

It is possible to have a project directory (even though a bit messy) that will compile in both Microsoft Visual Studio and in GCC without having to change a lick of code. Thats child's play for a simple project, but its still possible even for a project that contains a main executable and several other dynamic libraries.

So first off, since we are dynamically linking, we are definitely going to have function pointers returned by dlsym(...) or GetProcAddress(...). The actual DLL/SO modules export only three functions--one to create the instance, one to destroy it, and one to return the version. So we have the typedefs for these as so:

 
typedef int (*fpCreateRendererInterface)(CRenderer **pInterface);
typedef int (*fpDestroyRendererInterface)(CRenderer **pInterface);
typedef int (*fpQueryRendererVersion)(void);
 

Second off, this is platform independent, so obviously we will need to be using some fancy pre-processor conditionals (PPCs) to detect the platform / compiler. Now in certain instances we only want to know what the compiler is, because the actual platform doesn't matter, but in other cases we want to know the actual platform as well because the same compiler is used on multiple platforms (GCC is used in Linux and also Mac). First for the compiler, we can detect Visual C++ by checking to see if _MSC_VER is defined, and we can detect GCC by checking to see if __GNUC__ is defined. For the platform, we can detect Windows by checking if WIN32 is defined (yes, even 64-bit Windows defines this), we can detect Linux by checking if __linux__ is defined, and we can detect OSX by checking if __MACH__ and __APPLE__ are defined.

We can then use these PPCs to create code that is savagely flexible. In this singleton class, I have a static void pointer to the library (Windows' HMODULE is just a void*, don't let them trick you) called m_hLibrary. Lets see how we could dynamically link either a .so file in Linux or a .dll file in Windows and place the returned handle in the same variable... here is the code for the "SGL" (SDL GL) renderer type which can be used in either Linux or Windows, taking into account if the code is in release or debug mode:

 
case rstSGL:
	Log::Entry(-1,__FILE__,__LINE__,"Creating SGL rendering interface...");
#if defined(__GNUC__)
 
#if defined(NDEBUG)
	Log::Entry(-1,__FILE__,__LINE__,"__GNUC__ defined... opening release library");
	m_hLibrary = dlopen("./libRendererSGL.so",RTLD_NOW);
#else
	Log::Entry(-1,__FILE__,__LINE__,"__GNUC__ defined... opening debug library");
	m_hLibrary = dlopen("../RendererSGL/bin/Debug/libRendererSGL.so",RTLD_NOW);
#endif
	if(!m_hLibrary)
		Log::Entry(2,__FILE__,__LINE__,"Error loading shared library. dlerror() = %s",dlerror());
#elif defined(_MSC_VER)
#if defined(NDEBUG)
	m_hLibrary = LoadLibraryExA("RendererSGL.dll",NULL,NULL);
#else
	m_hLibrary = LoadLibraryExA("../RendererSGL/bin/Debug/RendererSGL.dll",NULL,NULL);
#endif
#endif
	break;
 

Please note that NDEBUG is not defined by GCC even when using -O2, so you need to set your release target to define this manually (-D NDEBUG). I find it strange because it is supposedly a standard...

Also note that when linking using dlopen(...), we specify RTLD_NOW to force resolution of all symbols in the dynamic library. If we used RTLD_LAZY, we could exclude a lot of code from our library, and let it resolve symbols later (i.e. from the main executable). Unfortunately this works great on Linux but seemingly has no analogy in Windows, and in order to keep the projects symmetrical across platforms, we use RTLD_NOW to behave appropriately.

So lets look at whats going on here... its a bit over complicated, but I thought I would provide some extra good ideas for you guys. If using GCC, we use dlopen(...) to get the handle to the .so file, and if using VC++, we use LoadLibraryExA(...) to get the handle to the .dll file. If NDEBUG is defined, we link to the release version of the dynamic library (actually look in the current directory or system path as if it were a proper deployment), otherwise we link to the debug version of the library to simplify development.

Oh snap! So we now have linked to a dynamic library regardless of what platform we are running on! This is kickass, so where to now? We need to get pointers to the functions in the library we are going to use. The function that does this in Linux is dlsym(...), and in windows is GetProcAddress(...). Here is what this would look like in a platform independent form:

 
#if defined(__GNUC__)
	fpCreateRendererInterface IntCreate=(fpCreateRendererInterface)dlsym(m_hLibrary,"CreateInterface");
#elif defined(_MSC_VER)
	fpCreateRendererInterface IntCreate=(fpCreateRendererInterface)GetProcAddress((HMODULE)m_hLibrary,"CreateInterface");
#endif
 

Damn, its that easy? Indeed it is. We now have a function pointer to a procedure in a dynamically linked library regardless of if it came from a .so file in Linux or a .dll file in Windows. Obviously once armed with the function pointer, the remaining code is the same regardless of platform. We just use IntCreate(...) like it were a normal function. In this case we pass a pointer to a pointer to the pure virtual renderer base class, and inside the dynamic library, we assign the pointer to an instance of a derived class:

 
extern "C"
{
	int CreateInterface(CRenderer **pInterface)
	{
		if(*pInterface)
			return -1;
 
		*pInterface = new CRendererSGL();
 
		return 0;
	}
...
 

This is really quite powerful, and since the only actual call to an exported function is when creating the derived class instance, the performance hit while using the derived class is only from the vftable. More importantly this lets us do something ultra simple in our main code to get a reference to an abstract renderer interface that doesn't require knowledge of the nitty-gritty of either D3D or OpenGL:

 
	Log::Entry(0,__FILE__,__LINE__,"Creating rendering device...");
	Graphics::CreateInterface();
	CRenderer *renderer = Graphics::GetInterface();
	renderer->Initialize(0);
 
	if(g_bSafeDevice)
		renderer->CreateDeviceSafe();
	else
		renderer->CreateDevice(800, 600, 32, g_bWindowed);
 

Yeah, I know. That code is delicious. Its even more tasty when you have a CMesh that contains instances of pure virtual CResourceVtxBuff and CResourceIdxBuff created by the derived CRenderer class in the dynamic library, and CModel that contains a number of CMesh instances as well as a number of CMaterial instances that contain instances of pure virtual CResourceTexture also created by the derived CRenderer class in the dynamic library. So to create a model and render it, you would have to do something like the following:

 
	// example of loading a mesh
	mshOut = new CMesh();
	iStride=mshOut->GetVtxStride();
	mshOut->SetVtxCount(iVertexCount);
	mshOut->SetFaceCount(iFaceCount);
 
	m_pRenderer->CreateMeshBuffers(iStride*iVertexCount,sizeof(int)*3*iFaceCount,mshOut);
 
	// if pRenderer is D3D, this lock would be like IDirect3DVertexBuffer9->Lock(...),
	//while in OpenGL it would be like glMapBufferARB(...). Transparent at this point.
	VtxData=(unsigned char*)mshOut->GetVtxPtr()->LockWrite(0,0);
 
	// Write vertex buffer to VtxData here...
 
	mshOut->GetVtxPtr()->Unlock();
 
	IdxData=(unsigned char*)mshOut->GetIdxPtr()->LockWrite(0,0);
 
	// write index buffer to IdxData here..
 
	mshOut->GetIdxPtr()->Unlock();
 
	// example of loading a material
	mtlOut=new CMaterial();
	mtlOut->SetDiffuse(FloatToLongColor(v3fDiffuse.x, v3fDiffuse.y, v3fDiffuse.z));
	mtlOut->SetAmbient(FloatToLongColor(v3fAmbient.x, v3fAmbient.y, v3fAmbient.z));
	mtlOut->SetSpecular(FloatToLongColor(v3fSpecular.x, v3fSpecular.y, v3fSpecular.z));
	mtlOut->SetMaterialName(sMaterialName);
 
	mtlOut->SetTexture(m_pRenderer->CreateTexture(&imgTexture));
 
	// and you add them to a model which contains std::vectors of meshes and materials...
 
	iMaterialIdxList[j] = mdlOut->AddMaterial(mtlOut);
 
	//...
 
	mdlOut->AddMesh(mshOut,iMaterialIdxList[iMaterialRef]);
 
	// and eventually render!
 
	iMeshCount = mdlCurr->GetMeshCount();
 
	for(j=0;j<iMeshCount;j++)
	{
		pRenderer->SetWorld(&matWorld);
 
		k = mdlCurr->GetMeshMaterialIdx(j);
 
		pRenderer->SetTexture(mdlCurr->GetMaterial(k)->GetTexture());
		pRenderer->Render(mdlCurr->GetMesh(j));
	}
 

Anyway, I guess this isn't all that useful, and maybe I'm just showing off at this point. It does exhibit some good ideas, and show how glorious abstraction can be though. Regardless, I got distracted again. The NDS Wifi example continues. I will post in the next few days to describe the protocol used and give a little primer on sockets. Keep your eyes peeled.

Tags: , , ,

Impetus

Posted in Uncategorized on May 15th, 2009 by Chaos Engineer

Well, this is it. I've become a blogger.

I spend hours every day wrestling with new software tools and devising new feedback systems and ways to exploit those systems. Some ideas that rattle around in my head are too grand to implement directly, so I just mull over them for a period, and then often forget about them entirely. I could fill a library with all the great ideas I've forgotten.

I thought that perhaps given a medium where I could get those ideas written down and out in the open, perhaps I would benefit from them more. In the process, why not share them with those who are willing to listen... perhaps they can benefit from them as well?

The blogosphere is an increasingly crowded space. As much as I would like to have one place where I can vet all my ideas, there is a need to hone my focus. Deviating from this norm once in a while should be acceptable, but in the interest of keeping ChaosEngineer coherent these deviations should be kept as infrequent as possible.

Thus this will be a place where one can come to find technical insight on using Linux, OpenGL and various other open source technologies. The general focus of this usage will be for the purpose of creating, interfacing with, manipulating or visualizing chaotic systems. Getting Linux to do what you want, and then streamlining it would be part of this process as well. I hope to expose plenty of generally useful information along this somewhat narrow road.

Tags: , ,