m8ta
use https for features.
text: sort by
tags: modified
type: chronology
{319} is owned by tlh24.{725} is owned by tlh24.{816} is owned by tlh24.{346} is owned by tlh24.{406} is owned by tlh24.
[0] Hochberg LR, Serruya MD, Friehs GM, Mukand JA, Saleh M, Caplan AH, Branner A, Chen D, Penn RD, Donoghue JP, Neuronal ensemble control of prosthetic devices by a human with tetraplegia.Nature 442:7099, 164-71 (2006 Jul 13)

[0] Beurrier C, Bezard E, Bioulac B, Gross C, Subthalamic stimulation elicits hemiballismus in normal monkey.Neuroreport 8:7, 1625-9 (1997 May 6)

[0] Carmena JM, Lebedev MA, Crist RE, O'Doherty JE, Santucci DM, Dimitrov DF, Patil PG, Henriquez CS, Nicolelis MA, Learning to control a brain-machine interface for reaching and grasping by primates.PLoS Biol 1:2, E42 (2003 Nov)

[0] Carmena JM, Lebedev MA, Henriquez CS, Nicolelis MA, Stable ensemble performance with single-neuron variability during reaching movements in primates.J Neurosci 25:46, 10712-6 (2005 Nov 16)

[0] Churchland MM, Afshar A, Shenoy KV, A central source of movement variability.Neuron 52:6, 1085-96 (2006 Dec 21)

{644} hide/ /
Given proper implementation of fixed-point sine and cosine, we present the C portion of our microstepping controller below, hopefully commented to a sufficient extent to make it intelligible and to document the logic behind our design.

#include <msp430x54x.h>
#define INCR 1
#define PI2 (12868) //we use a 11 bit fixed-point representationf of motor angles.  
	// 12867 = 2*pi*2^11.  
#define TIMER_SCL	128
#define SHUTTER_CLOSED 	0 //defines used in the state-machine control of the shutter. 
#define SHUTTER_OPEN	1
#define SHUTTER_SMALL	2

	//Start of Stepper Motor Program
	//ME270 Project

short theta1 = 0; //the MSP430 is a 16-bit processor. 
short theta2 = 0; //hence, most datatypes should be 'short' for efficiency.
short theta1_v = 0; //we cannot control the poition of the stepper motors directly, 
short theta2_v = 0; // since we only have 3 bits of control from the parallel port. 
// also, direct position control of postion would cause the stepper to miss steps 
// smooth position change and limited acceleration is guaranteed by controlling the velocity. 

short shutter_state = 0; // none of the steppers have encoders, 
	// so we keep track of the shutter position here.  
short shutter_cmd ;  //this is set in ISR (interupt service routine) 
	// and read, and acted upon, in the main loop. 

short qsin(short i){
	//i goes from  0 pi/2 base 11 or... 
	// 0 to 3217
	short cube, fifth, result; 
	cube = mply_11(i,i);
	cube = mply_11(cube, i); 
	fifth = cube; 
	fifth = mply_11(fifth, i);
	fifth = mply_11(fifth, i); 
	//our approximation to sine based on taylor series: 
	//original: sin(x) = x - x^3/3! + x^5/5!
	//sin(x) = x - x^3/(8+32+128) + x^5/128 
	result = i - 
		((cube >> 3) + (cube >> 5) + (cube >> 7)) + (fifth >> 7);
	//result is base 11.  need it to be base 7. (0 to 127)
	result = result >> 4; 
	if(result > TIMER_SCL) result = TIMER_SCL; 
	return (short)result; 
}

// this is an even more simplified version of sin - 
// made in an attempt to make the microstepping smoother. 
// it turned out to not matter very much.  to get very smooth stepping , 
// may have to develop an inverse model of the nonlinear stepper motors 
// ** quantitatively **
short qsin2(short i){
	//i goes from  0 pi/2 base 11 or... 
	// 0 to 3217
	short cube, result; 
	cube = mply_11(i,i);
	cube = mply_11(cube, i); 
	//our approximation to sine based on taylor series: 
	//original: sin(x) = x - x^3/3! + x^5/5!
	//sin(x) = x - x^3/(8+32+128) + x^5/128 
	result = i - (cube >> 3) ;
	//result is base 11.  need it to be base 7. 
	result = result >> 4; 
	if(result > TIMER_SCL) result = TIMER_SCL; //maximum..
	return (short)result; 
}

short isin(short i){
	// i is base 2^11
	//but we accept 0 to 2*pi or 12867
	if(i >= 0 && i < 3217) return qsin(i); 
	else if(i >= 3217 && i < 6434) return qsin(6434 - i); 
	else if(i >= 6434 && i < 9651) return -1*qsin(i - 6434); 
	else if(i >= 9651 && i < 12867) return -1*qsin(12867 - i); 
	else return 0; 
}

short icos(short i){
	// i is base 2^11
	//but we accept 0 to 2*pi or 12867
	if(i >= 0 && i < 3217) return qsin(3217 - i); 
	else if(i >= 3217 && i < 6434) return -1*qsin(i - 3217); 
	else if(i >= 6434 && i < 9651) return -1*qsin(9651 - i); 
	else if(i >= 9651 && i < 12867) return qsin(i - 9651); 
	else return 0; 
}

//this interrupt is triggered by the parallel port. 
//because we only have 3 lines and need 8 commands, 
//after triggering (0 to 1 transition on PORT2.0 ), 
//the control program on the PC will either hold the pin up 
// (indicating a velocity step command) or drop it (indicating shutter/stop cmd). 

#pragma vector=PORT2_VECTOR
__interrupt void port2_ISR (void)
{
	//need to read the two pins to figure out which axis to change.
	short k; 
	for(k=0; k<8; k++){
		P9OUT ^= 0x4;	
	}
	switch(P2IN & 0x7){
		case 1: theta1_v += INCR;  break; 
		case 3: theta1_v -= INCR;  break; 
		case 5: theta2_v += INCR;  break; 
		case 7: theta2_v -= INCR;  break; 
		case 0: shutter_cmd = SHUTTER_CLOSED; break; 
		case 2: shutter_cmd = SHUTTER_SMALL; break; 
		case 6: shutter_cmd = SHUTTER_OPEN; break; 
		case 4: theta1_v = 0; theta2_v = 0; break;
	}
	P2IFG = 0; //clear the interupt. 
}

#pragma vector=TIMER1_A0_VECTOR 
__interrupt void timera1_ISR (void)
{
	return; //if this vector is not here and the interupt is enabled, then the proc will crash! 
}
// have to integrate the velocity at a consistent rate, 
// hence we pushed integration as well as the sine/cosine computation 
// into this timer interrupt. 
#pragma vector=TIMER1_A1_VECTOR 
__interrupt void timera11_ISR (void)
{
	short ps, pc; 
	P1OUT ^= 0xFF; //toggle P1 to indicate the update rate. (the led is there)
	TA1CTL = 0x0004; //reset counter
	TA1CTL = 0x0112; //turn back in interrupts.	

	theta1 += theta1_v; 
	theta2 += theta2_v;
	
	if(theta1 > PI2) theta1 -= PI2; 
	if(theta1 < 0) theta1 += PI2; 

	if(theta2 > PI2) theta2 -= PI2; 
	if(theta2 < 0) theta2 += PI2; 

	ps = isin(theta1)+TIMER_SCL;
	pc = icos(theta1)+TIMER_SCL;

	TA0CCR1 = ps; //update the counter (PWM output) registers. 
	TA0CCR4 = pc;

	ps = isin(theta2)+TIMER_SCL;
	pc = icos(theta2)+TIMER_SCL;
	
	TA0CCR2 = ps; 
	TA0CCR3 = pc;
	P1OUT ^= 0xFF; //toggle P1 to indicate the update rate. (the led is there)
	return;
}

//delay is used in moving the shutter. 
// too short, and the stepper motor controlling the shutter will skip steps! 
void delay(short time){
	short k; 
	short j = 0; 
	for(k=0; k<time; k++){
		j++; 
		j++; 
	}
}

void delay_long(short time){
	short k,j,f; 
	for(k=0; k<time; k++){
		f = 0; 
		for(j=0; j<100; j++){
			f++; 	
		}
	}
}

// ideally, we would ramp the shutter velocity up and down to maximize speed 
// and minimize time - constant velocity works fine and fast. 
#define SHUTDLY	1600
void shutter_ccw(void){
	P9OUT = 0x1; 
	delay(SHUTDLY); 
	P9OUT = 0x3; 
	delay(SHUTDLY); 
	P9OUT = 0x2; 
	delay(SHUTDLY); 
	P9OUT = 0x0; 
	delay(SHUTDLY); 	
}

void shutter_cw(void){
	P9OUT = 0x2; 
	delay(SHUTDLY); 
	P9OUT = 0x3; 
	delay(SHUTDLY); 
	P9OUT = 0x1; 
	delay(SHUTDLY); 
	P9OUT = 0x0; 
	delay(SHUTDLY); 	
}

void shutter_open(void){
	short i; 
	if(shutter_state == SHUTTER_CLOSED){
		//I was quite pleased to discover that the three shutters states
		// are exactly 5 full steps apart! 
		for(i=0; i<5; i++){ 
			shutter_ccw(); 	
		}

	}
	if(shutter_state == SHUTTER_SMALL){
		for(i=0; i<5; i++){
			shutter_cw(); 	
		}
	}
	shutter_state = SHUTTER_OPEN; 
}
void shutter_close(void){
	short i; 
	if(shutter_state == SHUTTER_OPEN){
		for(i=0; i<5; i++){
			shutter_cw(); 	
		}
	}
	if(shutter_state == SHUTTER_SMALL){
		for(i=0; i<10; i++){
			shutter_cw(); 	
		}
	}
	shutter_state = SHUTTER_CLOSED; 
}
void shutter_small(void){
	short i; 
	if(shutter_state == SHUTTER_OPEN){
		for(i=0; i<5; i++){
			shutter_ccw(); 	
		}
	}
	if(shutter_state == SHUTTER_CLOSED){
		for(i=0; i<10; i++){
			shutter_ccw(); 	
		}
	}
	shutter_state = SHUTTER_SMALL; 
}

void main (void){
	//SR = 0x02;
	short t1, t2, ps, pc; 
	short k; 
	WDTCTL = WDTPW + WDTHOLD; //stop the watchdog timer.
	// UCSCTL = Universal clock system control (registers). 
	// sets the core clock of the device. 
	_bis_SR_register(SCG0);
	//SR = SR | 0x40 ;
	// setup the digitally controlled oscillator. 
	UCSCTL0 = 0x0700; //DCO = 5, MOD = 0
	UCSCTL1 = 0x0060; //DCORSEL = 3, middle freq. 
	UCSCTL2 = 0x101F; //FLL (frequency locked loop); doesnt matter here.
	UCSCTL4 = 0x0333; //select DCOCLK for all clock sources 
	UCSCTL0 = 0x0900; //DCO = 9, MOD = 0
		// DCO = internal high-frequency oscillator). 
	//UCSCTL5 = 0x0000; 

	// setup timer A (for controlling PWM outputs)
	TA0CCR0 = TIMER_SCL*2+1; //Timer A end pulse
	TA0CCR1 = TIMER_SCL; //Timer A start pulse
	TA0CCR2 = TIMER_SCL; //Timer A start pulse
	TA0CCR3 = TIMER_SCL; //Timer A start pulse
	TA0CCR4 = TIMER_SCL; //Timer A start pulse
	TA0CTL = 0x0110; //TASSEL = ACLK; input divider=1; MCx = count up mode; 
	TA0CCTL0 = 0x0040; //sets the mode of the output: here=2, toggle/reset.
		// (produces pulses at 8Khz). 
	TA0CCTL1 = 0x00C0; //output mode: toggle/set. 
	TA0CCTL2 = 0x00C0; // same
	TA0CCTL3 = 0x00C0; // same
	TA0CCTL4 = 0x00C0; // same

	//setup timer B (for controlling theta & velocity updates). 
	TA1CCR0 = 10000; //Timer A end pulse
	TA1CCR1 = 5000; //Timer A start pulse
	TA1CCR2 = 5000; //Timer A start pulse	
	TA1CTL = 0x0004;
	TA1CTL = 0x0112; //TASSEL = ACLK; input divider=1; MCx = count up mode; 
	TA1CCTL0 = 0x0050; //sets the mode of the output: here=2, toggle/reset.
		// (produces pulses at 8Khz). 
	TA1CCTL1 = 0x00C0; //output mode: toggle/set. 
	TA1CCTL2 = 0x00C0; // same
	
	P1DIR = 0x03; //P1.0 and P1.1 to output. (the LED)
	P1SEL = 0x00;
	P1OUT = 0; 
		
	P8DIR = 0xFF; //for some reason Port 1 does not work for the dev board --  
	P8SEL = 0x7F; //hence, we switched over to Port 8, which also is connected 
	// to the timers. 
	// the P8SEL register selects the timer output as opposed to general purpose IO. 
	
	//setup port2 (computer command via parallel port) interrupt. 
	P2DIR = 0; //all inputs. 
	P2IFG = 0;
	P2IE = 0x01; //enable interupts on P2.0
	P2IES = 0; // low to high edge detect. 
	_bis_SR_register(GIE | SCG0 );  //enable interrupts, dont go to sleep.
	
	P9DIR = 0x07; 
	
	//test the shutter. first move all the way to the limit.
	// since we do not know the initial position.
	for(k=0; k<30; k++){
		shutter_cw(); 
	}
	shutter_ccw();  //step one out so we don't hit the limits later.
	shutter_state = SHUTTER_CLOSED; //this is where the init will leave it
	while(1){
		//now just sit here waiting for a shutter command from the 
		// parallel port ISR.  
		if(shutter_state != shutter_cmd){
			switch(shutter_cmd){
				case SHUTTER_OPEN: shutter_open(); break; 
				case SHUTTER_CLOSED: shutter_close(); break; 
				case SHUTTER_SMALL: shutter_small(); break;
			} 	
		}
	}
}

We has some problem getting Port1 to work, hence had to use Port8 to get the PWM signals out -- see below. Note the shutter does not need to be microstepped and instead can be controlled as per a conventional stepper motor. The pins used are marked in yellow; pin 57 is a simple pulse output.

Note that each PWM signal is generated from the same timer counter, hence they are synchronous (this is of course not necessary). Below are some examples of two phases of one motor output; in real life, of course, the PWM ratio continually changes.

Below is the development board being probed to produce the plots above.

We then used the pinouts of the NXP microcontrollers, intuited last time by probing their on-line function (specifically the auto-calibration sequence upon startup), to wire up a harness for external control of the H-bridges. Below is a picture of that (we removed the original microcontrollers to prevent contention), and the associated wiring labels.

The next task was to make a 5V to 3.2V regulator (the MSP430 only runs at 3.2V, max), nothing major just a LM317. See below.

Finally, everything was wired together. The 3.2 V supply was jumpered, as the MSP430 USB programmer provided its own power. (Amazingly, the ultra low power MSP430 could run on power from the parallel port, too!)

A level translator is needed to properly interface the 3.2V MSP430 to the 5V parallel port - we canibalized a spare JTAG adapter for this purpose. It was this that limited us to only 3 bits of control.

And that, minus the difficulty we had getting the compiler working properly, is the entirety of the microcontroller part of the project.

{648} hide/ /

Given proper implementation of fixed-point sine and cosine, we present the C portion of our microstepping controller below, hopefully commented to a sufficient extent to make it intelligible and to document the logic behind our design.

#include <msp430x54x.h>
#define INCR 1
#define PI2 (12868) //we use a 11 bit fixed-point representationf of motor angles.  
	// 12867 = 2*pi*2^11.  
#define TIMER_SCL	128
#define SHUTTER_CLOSED 	0 //defines used in the state-machine control of the shutter. 
#define SHUTTER_OPEN	1
#define SHUTTER_SMALL	2

	//Start of Stepper Motor Program
	//ME270 Project

short theta1 = 0; //the MSP430 is a 16-bit processor. 
short theta2 = 0; //hence, most datatypes should be 'short' for efficiency.
short theta1_v = 0; //we cannot control the poition of the stepper motors directly, 
short theta2_v = 0; // since we only have 3 bits of control from the parallel port. 
// also, direct position control of postion would cause the stepper to miss steps 
// smooth position change and limited acceleration is guaranteed by controlling the velocity. 

short shutter_state = 0; // none of the steppers have encoders, 
	// so we keep track of the shutter position here.  
short shutter_cmd ;  //this is set in ISR (interupt service routine) 
	// and read, and acted upon, in the main loop. 

short qsin(short i){
	//i goes from  0 pi/2 base 11 or... 
	// 0 to 3217
	short cube, fifth, result; 
	cube = mply_11(i,i);
	cube = mply_11(cube, i); 
	fifth = cube; 
	fifth = mply_11(fifth, i);
	fifth = mply_11(fifth, i); 
	//our approximation to sine based on taylor series: 
	//original: sin(x) = x - x^3/3! + x^5/5!
	//sin(x) = x - x^3/(8+32+128) + x^5/128 
	result = i - 
		((cube >> 3) + (cube >> 5) + (cube >> 7)) + (fifth >> 7);
	//result is base 11.  need it to be base 7. (0 to 127)
	result = result >> 4; 
	if(result > TIMER_SCL) result = TIMER_SCL; 
	return (short)result; 
}

// this is an even more simplified version of sin - 
// made in an attempt to make the microstepping smoother. 
// it turned out to not matter very much.  to get very smooth stepping , 
// may have to develop an inverse model of the nonlinear stepper motors 
// ** quantitatively **
short qsin2(short i){
	//i goes from  0 pi/2 base 11 or... 
	// 0 to 3217
	short cube, result; 
	cube = mply_11(i,i);
	cube = mply_11(cube, i); 
	//our approximation to sine based on taylor series: 
	//original: sin(x) = x - x^3/3! + x^5/5!
	//sin(x) = x - x^3/(8+32+128) + x^5/128 
	result = i - (cube >> 3) ;
	//result is base 11.  need it to be base 7. 
	result = result >> 4; 
	if(result > TIMER_SCL) result = TIMER_SCL; //maximum..
	return (short)result; 
}

short isin(short i){
	// i is base 2^11
	//but we accept 0 to 2*pi or 12867
	if(i >= 0 && i < 3217) return qsin(i); 
	else if(i >= 3217 && i < 6434) return qsin(6434 - i); 
	else if(i >= 6434 && i < 9651) return -1*qsin(i - 6434); 
	else if(i >= 9651 && i < 12867) return -1*qsin(12867 - i); 
	else return 0; 
}

short icos(short i){
	// i is base 2^11
	//but we accept 0 to 2*pi or 12867
	if(i >= 0 && i < 3217) return qsin(3217 - i); 
	else if(i >= 3217 && i < 6434) return -1*qsin(i - 3217); 
	else if(i >= 6434 && i < 9651) return -1*qsin(9651 - i); 
	else if(i >= 9651 && i < 12867) return qsin(i - 9651); 
	else return 0; 
}

//this interrupt is triggered by the parallel port. 
//because we only have 3 lines and need 8 commands, 
//after triggering (0 to 1 transition on PORT2.0 ), 
//the control program on the PC will either hold the pin up 
// (indicating a velocity step command) or drop it (indicating shutter/stop cmd). 

#pragma vector=PORT2_VECTOR
__interrupt void port2_ISR (void)
{
	//need to read the two pins to figure out which axis to change.
	short k; 
	for(k=0; k<8; k++){
		P9OUT ^= 0x4;	
	}
	switch(P2IN & 0x7){
		case 1: theta1_v += INCR;  break; 
		case 3: theta1_v -= INCR;  break; 
		case 5: theta2_v += INCR;  break; 
		case 7: theta2_v -= INCR;  break; 
		case 0: shutter_cmd = SHUTTER_CLOSED; break; 
		case 2: shutter_cmd = SHUTTER_SMALL; break; 
		case 6: shutter_cmd = SHUTTER_OPEN; break; 
		case 4: theta1_v = 0; theta2_v = 0; break;
	}
	P2IFG = 0; //clear the interupt. 
}

#pragma vector=TIMER1_A0_VECTOR 
__interrupt void timera1_ISR (void)
{
	return; //if this vector is not here and the interupt is enabled, then the proc will crash! 
}
// have to integrate the velocity at a consistent rate, 
// hence we pushed integration as well as the sine/cosine computation 
// into this timer interrupt. 
#pragma vector=TIMER1_A1_VECTOR 
__interrupt void timera11_ISR (void)
{
	short ps, pc; 
	P1OUT ^= 0xFF; //toggle P1 to indicate the update rate. (the led is there)
	TA1CTL = 0x0004; //reset counter
	TA1CTL = 0x0112; //turn back in interrupts.	

	theta1 += theta1_v; 
	theta2 += theta2_v;
	
	if(theta1 > PI2) theta1 -= PI2; 
	if(theta1 < 0) theta1 += PI2; 

	if(theta2 > PI2) theta2 -= PI2; 
	if(theta2 < 0) theta2 += PI2; 

	ps = isin(theta1)+TIMER_SCL;
	pc = icos(theta1)+TIMER_SCL;

	TA0CCR1 = ps; //update the counter (PWM output) registers. 
	TA0CCR4 = pc;

	ps = isin(theta2)+TIMER_SCL;
	pc = icos(theta2)+TIMER_SCL;
	
	TA0CCR2 = ps; 
	TA0CCR3 = pc;
	P1OUT ^= 0xFF; //toggle P1 to indicate the update rate. (the led is there)
	return;
}

//delay is used in moving the shutter. 
// too short, and the stepper motor controlling the shutter will skip steps! 
void delay(short time){
	short k; 
	short j = 0; 
	for(k=0; k<time; k++){
		j++; 
		j++; 
	}
}

void delay_long(short time){
	short k,j,f; 
	for(k=0; k<time; k++){
		f = 0; 
		for(j=0; j<100; j++){
			f++; 	
		}
	}
}

// ideally, we would ramp the shutter velocity up and down to maximize speed 
// and minimize time - constant velocity works fine and fast. 
#define SHUTDLY	1600
void shutter_ccw(void){
	P9OUT = 0x1; 
	delay(SHUTDLY); 
	P9OUT = 0x3; 
	delay(SHUTDLY); 
	P9OUT = 0x2; 
	delay(SHUTDLY); 
	P9OUT = 0x0; 
	delay(SHUTDLY); 	
}

void shutter_cw(void){
	P9OUT = 0x2; 
	delay(SHUTDLY); 
	P9OUT = 0x3; 
	delay(SHUTDLY); 
	P9OUT = 0x1; 
	delay(SHUTDLY); 
	P9OUT = 0x0; 
	delay(SHUTDLY); 	
}

void shutter_open(void){
	short i; 
	if(shutter_state == SHUTTER_CLOSED){
		//I was quite pleased to discover that the three shutters states
		// are exactly 5 full steps apart! 
		for(i=0; i<5; i++){ 
			shutter_ccw(); 	
		}

	}
	if(shutter_state == SHUTTER_SMALL){
		for(i=0; i<5; i++){
			shutter_cw(); 	
		}
	}
	shutter_state = SHUTTER_OPEN; 
}
void shutter_close(void){
	short i; 
	if(shutter_state == SHUTTER_OPEN){
		for(i=0; i<5; i++){
			shutter_cw(); 	
		}
	}
	if(shutter_state == SHUTTER_SMALL){
		for(i=0; i<10; i++){
			shutter_cw(); 	
		}
	}
	shutter_state = SHUTTER_CLOSED; 
}
void shutter_small(void){
	short i; 
	if(shutter_state == SHUTTER_OPEN){
		for(i=0; i<5; i++){
			shutter_ccw(); 	
		}
	}
	if(shutter_state == SHUTTER_CLOSED){
		for(i=0; i<10; i++){
			shutter_ccw(); 	
		}
	}
	shutter_state = SHUTTER_SMALL; 
}

void main (void){
	//SR = 0x02;
	short t1, t2, ps, pc; 
	short k; 
	WDTCTL = WDTPW + WDTHOLD; //stop the watchdog timer.
	// UCSCTL = Universal clock system control (registers). 
	// sets the core clock of the device. 
	_bis_SR_register(SCG0);
	//SR = SR | 0x40 ;
	// setup the digitally controlled oscillator. 
	UCSCTL0 = 0x0700; //DCO = 5, MOD = 0
	UCSCTL1 = 0x0060; //DCORSEL = 3, middle freq. 
	UCSCTL2 = 0x101F; //FLL (frequency locked loop); doesnt matter here.
	UCSCTL4 = 0x0333; //select DCOCLK for all clock sources 
	UCSCTL0 = 0x0900; //DCO = 9, MOD = 0
		// DCO = internal high-frequency oscillator). 
	//UCSCTL5 = 0x0000; 

	// setup timer A (for controlling PWM outputs)
	TA0CCR0 = TIMER_SCL*2+1; //Timer A end pulse
	TA0CCR1 = TIMER_SCL; //Timer A start pulse
	TA0CCR2 = TIMER_SCL; //Timer A start pulse
	TA0CCR3 = TIMER_SCL; //Timer A start pulse
	TA0CCR4 = TIMER_SCL; //Timer A start pulse
	TA0CTL = 0x0110; //TASSEL = ACLK; input divider=1; MCx = count up mode; 
	TA0CCTL0 = 0x0040; //sets the mode of the output: here=2, toggle/reset.
		// (produces pulses at 8Khz). 
	TA0CCTL1 = 0x00C0; //output mode: toggle/set. 
	TA0CCTL2 = 0x00C0; // same
	TA0CCTL3 = 0x00C0; // same
	TA0CCTL4 = 0x00C0; // same

	//setup timer B (for controlling theta & velocity updates). 
	TA1CCR0 = 10000; //Timer A end pulse
	TA1CCR1 = 5000; //Timer A start pulse
	TA1CCR2 = 5000; //Timer A start pulse	
	TA1CTL = 0x0004;
	TA1CTL = 0x0112; //TASSEL = ACLK; input divider=1; MCx = count up mode; 
	TA1CCTL0 = 0x0050; //sets the mode of the output: here=2, toggle/reset.
		// (produces pulses at 8Khz). 
	TA1CCTL1 = 0x00C0; //output mode: toggle/set. 
	TA1CCTL2 = 0x00C0; // same
	
	P1DIR = 0x03; //P1.0 and P1.1 to output. (the LED)
	P1SEL = 0x00;
	P1OUT = 0; 
		
	P8DIR = 0xFF; //for some reason Port 1 does not work for the dev board --  
	P8SEL = 0x7F; //hence, we switched over to Port 8, which also is connected 
	// to the timers. 
	// the P8SEL register selects the timer output as opposed to general purpose IO. 
	
	//setup port2 (computer command via parallel port) interrupt. 
	P2DIR = 0; //all inputs. 
	P2IFG = 0;
	P2IE = 0x01; //enable interupts on P2.0
	P2IES = 0; // low to high edge detect. 
	_bis_SR_register(GIE | SCG0 );  //enable interrupts, dont go to sleep.
	
	P9DIR = 0x07; 
	
	//test the shutter. first move all the way to the limit.
	// since we do not know the initial position.
	for(k=0; k<30; k++){
		shutter_cw(); 
	}
	shutter_ccw();  //step one out so we don't hit the limits later.
	shutter_state = SHUTTER_CLOSED; //this is where the init will leave it
	while(1){
		//now just sit here waiting for a shutter command from the 
		// parallel port ISR.  
		if(shutter_state != shutter_cmd){
			switch(shutter_cmd){
				case SHUTTER_OPEN: shutter_open(); break; 
				case SHUTTER_CLOSED: shutter_close(); break; 
				case SHUTTER_SMALL: shutter_small(); break;
			} 	
		}
	}
}

We has some problem getting Port1 to work, hence had to use Port8 to get the PWM signals out -- see below. Note the shutter does not need to be microstepped and instead can be controlled as per a conventional stepper motor. The pins used are marked in yellow; pin 57 is a simple pulse output.

Note that each PWM signal is generated from the same timer counter, hence they are synchronous (this is of course not necessary). Below are some examples of two phases of one motor output; in real life, of course, the PWM ratio continually changes.

Below is the development board being probed to produce the plots above.

We then used the pinouts of the NXP microcontrollers, intuited last time by probing their on-line function (specifically the auto-calibration sequence upon startup), to wire up a harness for external control of the H-bridges. Below is a picture of that (we removed the original microcontrollers to prevent contention), and the associated wiring labels.

The next task was to make a 5V to 3.2V regulator (the MSP430 only runs at 3.2V, max), nothing major just a LM317. See below.

Finally, everything was wired together. The 3.2 V supply was jumpered, as the MSP430 USB programmer provided its own power. (Amazingly, the ultra low power MSP430 could run on power from the parallel port, too!)

A level translator is needed to properly interface the 3.2V MSP430 to the 5V parallel port - we canibalized a spare JTAG adapter for this purpose. It was this that limited us to only 3 bits of control.

And that, minus the difficulty we had getting the compiler working properly, is the entirety of the microcontroller part of the project.

[0] Isoda M, Hikosaka O, Switching from automatic to controlled action by monkey medial frontal cortex.Nat Neurosci 10:2, 240-8 (2007 Feb)

[0] Serruya MD, Hatsopoulos NG, Paninski L, Fellows MR, Donoghue JP, Instant neural control of a movement signal.Nature 416:6877, 141-2 (2002 Mar 14)

[0] Boline J, Ashe J, On the relations between single cell activity in the motor cortex and the direction and magnitude of three-dimensional dynamic isometric force.Exp Brain Res 167:2, 148-59 (2005 Nov)

[0] Ashe J, Georgopoulos AP, Movement parameters and neural activity in motor cortex and area 5.Cereb Cortex 4:6, 590-600 (1994 Nov-Dec)

[0] Schwartz AB, Cortical neural prosthetics.Annu Rev Neurosci 27no Issue 487-507 (2004)[1] Carmena JM, Lebedev MA, Henriquez CS, Nicolelis MA, Stable ensemble performance with single-neuron variability during reaching movements in primates.J Neurosci 25:46, 10712-6 (2005 Nov 16)

[0] Lavin A, Nogueira L, Lapish CC, Wightman RM, Phillips PE, Seamans JK, Mesocortical dopamine neurons operate in distinct temporal domains using multimodal signaling.J Neurosci 25:20, 5013-23 (2005 May 18)[1] Pirot S, Godbout R, Mantz J, Tassin JP, Glowinski J, Thierry AM, Inhibitory effects of ventral tegmental area stimulation on the activity of prefrontal cortical neurons: evidence for the involvement of both dopaminergic and GABAergic components.Neuroscience 49:4, 857-65 (1992 Aug)

[0] Brockwell AE, Rojas AL, Kass RE, Recursive bayesian decoding of motor cortical signals by particle filtering.J Neurophysiol 91:4, 1899-907 (2004 Apr)

[0] Marzullo TC, Miller CR, Kipke DR, Suitability of the cingulate cortex for neural control.IEEE Trans Neural Syst Rehabil Eng 14:4, 401-9 (2006 Dec)

{1417}
hide / / print
ref: -0 tags: synaptic plasticity 2-photon imaging inhibition excitation spines dendrites synapses 2p date: 05-31-2019 23:02 gmt revision:2 [1] [0] [head]

PMID-22542188 Clustered dynamics of inhibitory synapses and dendritic spines in the adult neocortex.

  • Cre-recombinase-dependent labeling of postsynapitc scaffolding via Gephryn-Teal fluorophore fusion.
  • Also added Cre-eYFP to lavel the neurons
  • Electroporated in utero e16 mice.
    • Low concentration of Cre, high concentrations of Gephryn-Teal and Cre-eYFP constructs to attain sparse labeling.
  • Located the same dendrite imaged in-vivo in fixed tissue - !! - using serial-section electron microscopy.
  • 2230 dendritic spines and 1211 inhibitory synapses from 83 dendritic segments in 14 cells of 6 animals.
  • Some spines had inhibitory synapses on them -- 0.7 / 10um, vs 4.4 / 10um dendrite for excitatory spines. ~ 1.7 inhibitory
  • Suggest that the data support the idea that inhibitory inputs maybe gating excitation.
  • Furthermore, co-inervated spines are stable, both during mormal experience and during monocular deprivation.
  • Monocular deprivation induces a pronounced loss of inhibitory synapses in binocular cortex.

{1462}
hide / / print
ref: -0 tags: 3D SHOT Alan Hillel Waller 2p photon holography date: 05-31-2019 22:19 gmt revision:4 [3] [2] [1] [0] [head]

PMID-29089483 Three-dimensional scanless holographic optogenetics with temporal focusing (3D-SHOT).

  • Pégard NC1,2, Mardinly AR1, Oldenburg IA1, Sridharan S1, Waller L2, Adesnik H3,4
  • Combines computer-generated holography and temporal focusing for single-shot (no scanning) two-photon photo-activation of opsins.
  • The beam intensity profile determines the dimensions of the custom temporal focusing pattern (CTFP), while phase, a previously unused degree of freedom, is engineered to make 3D holograph and temporal focusing compatible.
  • "To ensure good diffraction efficiency of all spectral components by the SLM, we used a lens Lc to apply a small spherical phase pattern. The focal length was adjusted so that each spectral component of the pulse spans across the short axis of the SLM in the Fourier domain".
    • That is, they spatially and temporally defocus the pulse to better fill the SLM. The short axis of the SLM in this case is Y, per supplementary figure 2.
  • The image of the diffraction grating determines the plane of temporal focusing (with lenses L1 and L2); there is a secondary geometric focus due to Lc behind the temporal plane, which serves as an aberration.
  • The diffraction grating causes the temporal pattern to scan to produce a semi-spherical stimulated area ('disc').
  • Rather than creating a custom 3D holographic shape for each neuron, the SLM is after the diffraction grating -- it imposes phase and space modulation to the CTFP, effectively convolving it with a holograph of a cloud of points & hence replicating at each point.

{1435}
hide / / print
ref: -0 tags: Na Ji 2p two photon fluorescent imaging pulse splitting damage bleaching date: 05-31-2019 19:55 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-18204458 High-speed, low-photodamage nonlinear imaging using passive pulse splitters

  • Core idea: take a single pulse and spread it out to N=2 kN= 2^k pulses using reflections and delay lines.
  • Assume two optical processes, signal SI αS \propto I^{\alpha} and photobleaching/damage DI βD \propto I^{\beta} , β>α>1\beta \gt \alpha \gt 1
  • Then an NN pulse splitter requires N 11/αN^{1-1/\alpha} greater average power but reduces the damage by N 1β/α.N^{1-\beta/\alpha}.
  • At constant signal, the same NN pulse splitter requires N\sqrt{N} more power, consistent with two photon excitation (proportional to the square of the intensity: N pulses of N/N\sqrt{N}/N intensity, 1/N per pulse fluorescence, Σ1\Sigma \rightarrow 1 overall fluorescence.)
  • This allows for shorter dwell times, higher power at the sample, lower damage, slower photobleaching, and better SNR for fluorescently labeled slices.
  • Examine the list of references too, e.g. "Multiphoton multifocal microscopy exploiting a diffractive optical element" (2003)

{1459}
hide / / print
ref: -2018 tags: Michael Levin youtube talk NIPS 2018 regeneration bioelectricity organism patterning flatworm date: 04-09-2019 18:50 gmt revision:1 [0] [head]

What Bodies Think About: Bioelectric Computation Outside the Nervous System - NeurIPS 2018

  • Short notes from watching the video, mostly interesting factoids: (This is a somewhat more coordinated narrative in the video. Am resisting ending each of these statements with and exclamation point).
  • Human children up to 7-11 years old can regenerate their fingertips.
  • Human embryos, when split in half early, develop into two normal humans; mouse embryos, when squished together, make one normal mouse.
  • Butterflies retain memories from their caterpillar stage, despite their brains liquefying during metamorphosis.
  • Flatworms are immortal, and can both grow and contract, as the environment requires.
    • They can also regenerate a whole body from segments, and know to make one head, tail, gut etc.
  • Single cell organisms, e.g. Lacrymaria, can have complex (and fast!) foraging / hunting plans -- without a brain or anything like it.
  • Axolotl can regenerate many parts of their body (appendages etc), including parts of the nervous system.
  • Frog embryos can self-organize an experimenter jumbled body plan, despite the initial organization having never been experienced in evolution.
  • Salamanders, when their tail is grafted into a foot/leg position, remodel the transplant into a leg and foot.
  • Neurotransmitters are ancient; fungi, who diverged from other forms of life about 1.5 billion years ago, still use the same set of inter-cell transmitters e.g. serotonin, which is why modulatory substances from them have high affinity & a strong effect on humans.
  • Levin, collaborators and other developmental biologists have been using voltage indicators in embryos ... this is not just for neurons.
  • Can make different species head shapes in flatworms by exposing them to ion-channel modulating drugs. This despite the fact that the respective head shapes are from species that have been evolving separately for 150 million years.
  • Indeed, you can reprogram (with light gated ion channels, drugs, etc) to body shapes not seen in nature or not explored by evolution.
    • That said, this was experimental, not by design; Levin himself remarks that the biology that generates these body plans is not known.
  • Flatworms can sore memory in bioelectric networks.
  • Frogs don't normally regenerate their limbs. But, with a drug cocktail targeting bioelectric signaling, they can regenerate semi-functional legs, complete with nerves, muscle, bones, and cartilage. The legs are functional (enough).
  • Manipulations of bioelectric signaling can reverse very serious genetic problems, e.g. deletion of Notch, to the point that tadpoles regain some ability for memory creation & recall.

  • I wonder how so much information can go through a the apparently scalar channel of membrane voltage. It seems you'd get symbol interference, and that many more signals would be required to pattern organs.
  • That said, calcium is used a great many places in the cell for all sorts of signaling tasks, over many different timescales as well, and it doesn't seem to be plagued by interference.
    • First question from the audience was how cells differentiate organismal patterning signals and behavioral signals, e.g. muscle contraction.

{1384}
hide / / print
ref: -0 tags: NET probes SU-8 microfabrication sewing machine carbon fiber electrode insertion mice histology 2p date: 12-29-2017 04:38 gmt revision:1 [0] [head]

PMID-28246640 Ultraflexible nanoelectronic probes form reliable, glial scar–free neural integration

  • SU-8 asymptotic H2O absorption is 3.3% in PBS -- quite a bit higher than I expected, and higher than PI.
  • Faced yield problems with contact litho at 2-3um trace/space.
  • Good recordings out to 4 months!
  • 3 minutes / probe insertion.
  • Fab:
    • Ni release layer, Su-8 2000.5. "excellent tensile strength" --
      • Tensile strength 60 MPa
      • Youngs modulus 2.0 GPa
      • Elongation at break 6.5%
      • Water absorption, per spec sheet, 0.65% (but not PBS)
    • 500nm dielectric; < 1% crosstalk; see figure S12.
    • Pt or Au rec sites, 10um x 20um or 30 x 30um.
    • FFC connector, with Si substrate remaining.
  • Used transgenic mice, YFP expressed in neurons.
  • CA glue used before metabond, followed by Kwik-sil silicone.
  • Neuron yield not so great -- they need to plate the electrodes down to acceptable impedance. (figure S5)
    • Measured impedance ~ 1M at 1khz.
  • Unclear if 50um x 1um is really that much worse than 10um x 1.5um.
  • Histology looks realyl great, (figure S10).
  • Manuscript did not mention (though the did at the poster) problems with electrode pull-out; they deal with it in the same way, application of ACSF.

{1323}
hide / / print
ref: -0 tags: berkeley airbears2 configuration linux debian 8.1 date: 08-13-2015 23:42 gmt revision:1 [0] [head]

{1302}
hide / / print
ref: -0 tags: kevlar electrodes flexible polymer 12um McNaughton Utah date: 10-11-2014 00:19 gmt revision:0 [head]

PMID-8982987 Metallized polymer fibers as leadwires and intrafascicular microelectrodes

  • McNaughton TG1, Horch KW.
  • Ti/W, Au, Pt metalization via sputtering.
  • 12um core diamater.
  • demonstrate 8 month reliability.
  • 1um dipped silicone elastomer insulation.
  • note difficulty in manufactuing the fibers. No kidding!
  • Tensile strength the same as a 25um Pt-Ir wire, 90x more flexible.

{1277}
hide / / print
ref: -0 tags: polyimide anodic release 2005 date: 06-16-2014 23:58 gmt revision:1 [0] [head]

IEEE-1416914 (pdf) Partial release and detachment of microfabricated metal and polymer structures by anodic metal dissolution

  • recommend 100nm Cr/Al release layer.
  • finished devices just 'float to the surface' of saline solution.

{1269}
hide / / print
ref: -0 tags: hinton convolutional deep networks image recognition 2012 date: 01-11-2014 20:14 gmt revision:0 [head]

ImageNet Classification with Deep Convolutional Networks

{1255}
hide / / print
ref: -0 tags: Disseroth Kreitzer parkinsons optogenetics D1 D2 6OHDA date: 09-30-2013 18:15 gmt revision:0 [head]

PMID-20613723 Regulation of parkinsonian motor behaviors by optogenetic control of basal ganglia circuitry

  • Kravitz AV, Freeze BS, Parker PR, Kay K, Thwin MT, Deisseroth K, Kreitzer AC.
  • Generated mouse lines with channelrhodopsin2, with Cre recombinase under control of regulatory elements for the dopamine D1 (direct) or D2 (indirect) receptor.
  • optogenetic exitation of the indirect pathway elicited a parkinsonian state: increased freezing, bradykinesia and decreased locomotor initiations;
  • Activation of the direct pathway decreased freezing and increased locomotion.
  • Then: 6OHDA depletion of striatal dopamine neurons.
  • Optogenetic activation of direct pathway (D1 Cre/loxp) neurons restored behavior to pre-lesion levels.
    • Hence, this seems like a good target for therapy.

{1237}
hide / / print
ref: -0 tags: winslow Tresco 2010 BBB histology immune response microelectrodes date: 04-19-2013 23:25 gmt revision:0 [head]

PMID-19963267 Quantitative analysis of the tissue response to chronically implanted microwire electrodes in rat cortex.

  • Winslow BD, Tresco PA.
  • The spatial distribution of biomarkers associated with the foreign body response to insulated microwires placed in rat cerebral cortex was analyzed 2, 4, and 12 weeks after implantation using quantitative methods.
  • We found no evidence that reactive gliosis increases over time or that neuronal loss is progressive, we did find evidence of persistent inflammation and enhanced BBB permeability at the electrode brain tissue interface that extended over the 3 month indwelling period and that exhibited more animal to animal variability at 3 months than at 2 and 4 weeks.

{781}
hide / / print
ref: Polikov-2005.1 tags: neural response glia histology immune electrodes recording 2005 Tresco Michigan microglia date: 01-29-2013 00:34 gmt revision:10 [9] [8] [7] [6] [5] [4] [head]

PMID-16198003[0] Response of brain tissue to chronically implanted neural electrodes

  • Good review (the kind where figures are taken from other papers). Nothing terribly new (upon a very cursory inspection)
  • When CNS damage severs blood vessels, microglia are indistinguishable from the blood borne, monocyte-derived macrophages that are recruited by the degranulation of platelets and the cellular release of cytokines.
  • Furthermore, microglia are known to secrete, either constitutively, or in response to pathological stimuli, neurotrophic factors that aid in neuronal survival and growth.
    • Also release cytotoxic and neurotoxic factors that can lead to neuronal death in vitro.
    • It has been suggested that the presence of insoluble materials in the brain may lead to a state of 'frustrated phagocytosis' or inability of the macrophages to remove the foreign body, resulting in persistent release of neurotoxic substances.
  • When a 10x10 array of silicon probes was implanted in feline cortex, 60% of the needle tracks showed evidence of hemorrhage and 25% showed edema upon explantation of the probes after one day (Schmidt et al 1993) {1163}
    • Although a large number of the tracks were affected, only 3-5% of the area was actually covered by hemorrhages and edema, suggesting the actual damage to blood vessels may have been relatively minor. (!!)
  • Excess fluid and cellular debris diminishes 6-8 days due to the action of activated microglia and re-absorption.
  • As testament to the transitory nature of this mechanically induced wound healing response, electrode tracks could not be found in animals after several months when the electrode was inerted and quickly removed (Yuen and Agnew 1995, Rousche et al 2001; Csicsvari et al 2003, Biran et al 2005).
  • Biran et al 2005: observed persistent ED-1 immunoreactivity around silicon microelectrode arrays implanted in rat cortex at 2 and 4 weeks following implantation; not seen in microelectrode stab wound controls.
  • On the glial scar:
    • observed in the CNS of all vertebrates, presumably to isolate damaged parts of the nervous system and maintain the integrity of the blood-brain barrier.
    • mostly composed of reactive astrocytes.
    • presumably the glial scar insulates electrodes from nearby neurons, hindering diffusion and increasing impedance.
  • On the meninges:
    • Meningeal fibroblasts, which also stain for vimentin, but not for GFAP, may migrate down the electrode shaft from the brain surface and form the early basis for the glial scar.
  • On recording quality:
    • Histological examination upon explantation revealed that every electrode with stable unit recordings had at least one large neuron near the electrode tip, while every electrode that was not able to record resolvable action potentials was explanted from a site with no large neurons nearby.
  • Perhaps the clearest example of this variability was observed in the in vivo response to plastic “mock electrodes” implanted in rabbit brain by Stensaas and Stensaas (1976) {1210} and explanted over the course of 2 years. They separated the response into three types: Type 1 was characterized by little to no gliosis with neurons adjacent to the implant, Type 2 had a reactive astrocyte zone, and Type 3 exhibited a layer of connective tissue between the reactive astrocyte layer and the implant, with neurons pushed more than 100 um away. All three responses are well documented in the literature; however this study found that the model electrodes produced all three types of reactions simultaneously,depending on where along the electrode one looked.

____References____

[0] Polikov VS, Tresco PA, Reichert WM, Response of brain tissue to chronically implanted neural electrodes.J Neurosci Methods 148:1, 1-18 (2005 Oct 15)

{913}
hide / / print
ref: Ganguly-2011.05 tags: Carmena 2011 reversible cortical networks learning indirect BMI date: 01-23-2013 18:54 gmt revision:6 [5] [4] [3] [2] [1] [0] [head]

PMID-21499255[0] Reversible large-scale modification of cortical networks during neuroprosthetic control.

  • Split the group of recorded motor neurons into direct (decoded and controls the BMI) and indirect (passive) neurons.
  • Both groups showed changes in neuronal tuning / PD.
    • More PD. Is there no better metric?
  • Monkeys performed manual control before (MC1) and after (MC2) BMI training.
    • The majority of neurons reverted back to original tuning after BC; c.f. [1]
  • Monkeys were trained to rapidly switch between manual and brain control; still showed substantial changes in PD.
  • 'Near' (on same electrode as direct neurons) and 'far' neurons (different electrode) showed similar changes in PD.
    • Modulation Depth in indirect neurons was less in BC than manual control.
  • Prove (pretty well) that motor cortex neuronal spiking can be dissociated from movement.
  • Indirect neurons showed decreased modulation depth (MD) -> perhaps this is to decrease interference with direct neurons.
  • Quote "Studies of operant conditioning of single neurons found that conconditioned adjacent neurons were largely correlated with the conditioned neurons".
    • Well, also: Fetz and Baker showed that you can condition neurons recorded on the same electrode to covary or inversely vary.
  • Contrast with studies of motor learning in different force fields, where there is a dramatic memory trace.
    • Possibly this is from proprioception activating the cerebellum?

Other notes:

  • Scale bars on the waveforms are incorrect for figure 1.
  • Same monkeys as [2]

____References____

[0] Ganguly K, Dimitrov DF, Wallis JD, Carmena JM, Reversible large-scale modification of cortical networks during neuroprosthetic control.Nat Neurosci 14:5, 662-7 (2011 May)
[1] Gandolfo F, Li C, Benda BJ, Schioppa CP, Bizzi E, Cortical correlates of learning in monkeys adapting to a new dynamical environment.Proc Natl Acad Sci U S A 97:5, 2259-63 (2000 Feb 29)
[2] Ganguly K, Carmena JM, Emergence of a stable cortical map for neuroprosthetic control.PLoS Biol 7:7, e1000153 (2009 Jul)

{270}
hide / / print
ref: Hochberg-2006.07 tags: BMI Donoghue Utah probe Nature tetraplegia Hochberg 2006 date: 01-23-2013 18:49 gmt revision:4 [3] [2] [1] [0] [head]

PMID-16838014[] Neuronal ensemble control of prosthetic devices by a human with tetraplegia

  • patient was able to talk?
  • 96-channel microelectrode array implanted in arm/hand knob or right precentral gyrus.
  • around 30 units / day observed.
  • 90% of units showed significantly varied firing rates (K-S test) during imagined movements.
  • 2D control. Good pursuit tracking and center-out performance.
  • Used Wiener filter.
  • also see the technology review

____References____

{142}
hide / / print
ref: Schalk-2000.12 tags: error potential EEG wadsworth BCI 2000 BMI date: 01-23-2013 07:15 gmt revision:3 [2] [1] [0] [head]

PMID-11090763[0] EEG-based communication: presence of an error potential.

  • Idea: they trained a set of subjects to use mu/beta rhythm over central sulcus (sensorimotor) amplitude to move a cursor around the screen, and simultaneously monitored for error-related potentials to correct errors in decoding.
  • patients get 80-97% accuracy in a binary choice task.
  • look at the end of a trial to see if they 'approve' of the choice.
  • had to remove eyeblink artifacts! however, people tend to defer eyeblinks until the end of performance.
  • error = average EEG during error trials - EEG during correct trial. (a potential)
    • the error was over primary motor/ somatosensory cortex.
    • used adaptive noise cancellation to remove some of the eyeblink EMG.

____References____

[0] Schalk G, Wolpaw JR, McFarland DJ, Pfurtscheller G, EEG-based communication: presence of an error potential.Clin Neurophysiol 111:12, 2138-44 (2000 Dec)

{1178}
hide / / print
ref: -0 tags: parylene flexible neural recording drug delivery microfluidics 2012 inserter needle release date: 01-02-2013 22:41 gmt revision:1 [0] [head]

PMID-23160191 Novel flexible Parylene neural probe with 3D sheath structure for enhancing tissue integration

  • They seem to think that drugs are critical for success: "These features will enhance tissue integration and improve recording quality towards realizing reliable chronic neural interfaces."
  • Similar to Kennedy: "The sheath structure allows for ingrowth of neural processes leading to improved tissue/probe integration post implantation." 8 electrodes, 4 on the cone interior, 4 on the exterior.
    • opening is 50um at tip, 300 um at base.
  • Used a PEEK-stiffened parylene ZIF connection.
  • Only tested in agarose, but it did properly release from the inserter needle.
  • I wonder if we could use a similar technique..
  • "Lab on a chip" journal (Royal society of Chemistry). nice.

{1175}
hide / / print
ref: -0 tags: flexible polymer neural probes compliant MIT EPFL 2008 date: 12-22-2012 01:28 gmt revision:0 [head]

Demonstration of cortical recording using novel flexible polymer neural probes

  • Two layer platinum process minimizes probe size -- nice. Might be useful for our purposes.
  • used electrochemical etching to release the lithographically patterned devices from the sacrificial aluminum layer.
  • Impedance looks pretty high -- 500k at 1kHz.
  • They talk about PCA as though it's unusual to them (?)
  • Histology uncontrolled and un-quantitiative.

{923}
hide / / print
ref: Freire-2011.01 tags: Nicolelis BMI electrodes immune respones immunohistochemistry chronic arrays rats 2011 MEA histology date: 06-29-2012 01:20 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-22096594[0] Comprehensive analysis of tissue preservation and recording quality from chronic multielectrode implants.

  • Says what might be expected: tungsten microelectrode arrays work, though the quality gradually declines over 6 months.
  • Histological markers correlated well with recording performance.
  • Shows persistent glial activation around electrode sites + cell body hypertropy.
    • Suggest that loss in recording quality may be due to glial encapsulation.
  • References
    • Szarowski et al 2003 {1028}
    • Ward et al 2009
  • Histology:
    • NADPH-d: nicotinamide adenine dinucleotide phosphate-diaphorase, via beta-NADP
    • CO: cytochrome oxidase, via diamnibenzidine DAB, cytochrome c and catalase.
      • both good for staining cortical layers; applied in a standard buffered solution and monitored to prevent overstaining.
  • Immunohistochemistry:
    • Activated microglia with ED-1 antibody.
    • Astrocytes labeled with glial fibrillary acid protein.
    • IEG with an antibody against EGR-1, 'a well-known marker of calcium dependent neuronal activity'
    • Neurofilament revealed using a monoclonal NF-M antibody.
    • Caspace-3 with the associated antibody
    • Details the steps for immunostaining -- wash, blocknig buffer, addition of the antibody in diluted blocking solution (skim milk) overnight, wash again, incubate in biotinylated secondary antibody, wash again, incubate in avidin-biotin-peroxidase solution.
    • Flourescent immunohistochemistry had biotynlation replaced with alexa Fluor 488-conjugated horse anti-mouse and Alexa Fluor 594-conjugated goat anti-rabbit overnight.

____References____

[0] Freire MA, Morya E, Faber J, Santos JR, Guimaraes JS, Lemos NA, Sameshima K, Pereira A, Ribeiro S, Nicolelis MA, Comprehensive analysis of tissue preservation and recording quality from chronic multielectrode implants.PLoS One 6:11, e27554 (2011)

{1145}
hide / / print
ref: -0 tags: distrupted oscillations Mallet 2008 6-OHDA globus pallidus date: 02-29-2012 01:15 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-19109506 Parkinsonian beta oscillations in the external globus pallidus and their relationship with subthalamic nucleus activity.

  • Rat 6-OHDA.
  • On rate model: Although synchronization of GP unit activity increased by almost 100-fold during beta oscillations, the mean firing rate of GP neurons decreased compared with controls.
  • Synchronized firing persisted across different brain states, suggesting hardwiring.
  • GP and STN are frequency aligned but phase skewed.
    • Lateral inhibition in GP seems essential / see model.
  • Suggest that GPe / STN could generate oscillations that propagate to the rest of the BG.
    • But then why is the cortex required?

{171}
hide / / print
ref: Boulet-2006.1 tags: hemiballismus PD parkinsons STN subtalamic DBS dyskinesia rats 2006 glutamate date: 02-22-2012 18:58 gmt revision:1 [0] [head]

PMID-17050715 Subthalamic Stimulation-Induced Forelimb Dyskinesias Are Linked to an Increase in Glutamate Levels in the Substantia Nigra Pars Reticulata

  • STN-HFS-induced forelimb dyskinesia was blocked by microinjection of the Glu receptor antagonist kynurenate into the SNr and facilitated by microinjection of a mixture of the Glu receptor agonists AMPA and NMDA into the SNr.
    • Well, that just makes sense. STN is excitatory, GPi is an output structure of the BG, and stimulation should activate the area.

{161}
hide / / print
ref: Bergman-1998.01 tags: basal ganglia globus pallidus electrophysiology parkinsons 2001 DBS date: 02-22-2012 18:52 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-9464684[0] Physiological aspects of information processing in the basal ganglia of normal and parkinsonian primates.

  • The firing of neurons in the globus pallidus of normal monkeys is almost always uncorrelated.
  • after MPTP treatment, the firing patterns of GP became correlated and oscillatory (see the figures!!)
  • dopamine must support normal segregation of the informational channels in the basal ganglia, and breakdown of this causes the pathology of PD.
  • has a decent diagram of the basal ganglia-thalamo-cortical circuits.
  • two different hypotheses of BG function: segregated and convergent. data support the former.

____References____

[0] Bergman H, Feingold A, Nini A, Raz A, Slovin H, Abeles M, Vaadia E, Physiological aspects of information processing in the basal ganglia of normal and parkinsonian primates.Trends Neurosci 21:1, 32-8 (1998 Jan)

{828}
hide / / print
ref: RodriguezOroz-2001.09 tags: STN SNr parkinsons disease single unit recording spain 2001 tremor oscillations DBS somatotopy organization date: 02-22-2012 18:24 gmt revision:12 [11] [10] [9] [8] [7] [6] [head]

PMID-11522580[0] The subthalamic nucleus in Parkinson's disease: somatotopic organization and physiological characteristics

  • Looks like they discovered exactly what we have discovered ... only in 2001. This is both good and bad.
    • From the abstract: "Neurones responding to movement were of the irregular or tonic type, and were found in the dorsolateral region of the STN. Neurones with oscillatory and low frequency activity did not respond to movement and were in the ventral one-third of the nucleus. Thirty-eight tremor-related neurones were recorded."
  • Again, from the abstract: "The findings of this study indicate that the somatotopic arrangement and electrophysiological features of the STN in Parkinson's disease patients are similar to those found in monkeys."
  • It may be that we want to test differential modulation / oscillation: look for differences between rest and activity, if there is sufficient support for both these in the files we have.
  • These people were much, much more careful about localization of their single-electrode tracks. E.g. they calculated electrode location relative the DBS electrode stereotatically, and referenced this to the postoperative MRI location of the treatment electrode.
  • Many more (32% of 350 neurons) responded to active or passive movement.
  • Of this same set, 15% (31 neurons) had a firing rate with rhythmical activity; 38 neurons had rhythmic activity associated with oscillatory EMG, but most of these were responsive to passive stimulation.
  • Autocorrelation of the neuronal bursting and tremor peaked at mean 7Hz, while autocorr. of EMG peaked at mean 5Hz.
  • This whole paragraph is highly interesting: ''The neuronal response associated with active movements was studied by simultaneous recording of neuronal EMG activity of the limbs. Five tremor-related neurons, recorded while a voluntary movement was performed, were available for analysis. Voluntary activation of a particular limb segment arrested the tremor. This was associated with a change in the discharges of the recorded neuron, which fired at a slower rate and in synchrony with the voluntary movement. On occasions, freezing of the voluntary movement ensued and tremor reappeared, changing the neuronal activity back to the typical 4-5Hz tremor-related activity. The cross-correlation analysis of two such neurons showed a peak frequency of 4.63 and 4.88 Hz for tremor-related activity, and 1.5 to 1.38 Hz during voluntary movement. Whether neuronal discharges in the STN preceded or followed EMG activity of the limbs could not be precisely established under the present conditions.
  • Somatotopic representation in the STN is expected from normal and MTPT-treated monkeys. Indeed, somatotopy is enhanced int he GPm of MTPT-treated monkeys.
    • This somatotopy is likely to result from organized afferent from the primary motor cortex (M1) to dorsolateral STN; this is the target of DBS treatment. Ventral and medial STN seems to project to associative and limbic cortical regions.
    • It seems they think the STN is generally not diseased, it is just a useful target for stimulating without evoked movement as in M1. This is consistent with optogenetic studies by Deisseroth [1].
    • Supporting this: "DBS of STN in Parkinson's disease improves executive motor functions, but aggravates conditional associative learning.
  • Interesting: In Parkinson's disease patients with tremor, Levy and colleagues found synchronization and a high firing rate (>10Hz) while recording pairs of neurons >600um apart.
  • Recordings of cortical activity through EEG and STN LFP showed significant coherence in the beta and gamma frequency bands during movement - consistent with corticosubthalamic motor projection. ... and suggest that the STN neurons involved in parkinsonian tremor are the same as the ones ativated during the performance of a voluntary movement. (! -- I agree with this.)
  • More: The reciprocal inhibitory-excitatory connections tightly linking the GPe and the STN may generate self-perpetuating oscillations.

Old notes:

  • this paper concentrates on STN electrophysiology in PD.
    • has a rather excellent list of references.
  • found a somatotopic organization in the STN, with most motor-related units more irregular and in the dorsolateral STN.
  • found a substantial fraction of tremor-synchronized neurons.
  • conclude that the somatotopic organization is about the same as in monkeys (?) (!)
  • M1 projects to STN, as verified through anterograde tracing studies. [1] These neurons increase their firing rate in response to passive movements.
  • there appears to be a relatively-complete representation of the body in the dorsolateral STN.

____References____

[0] Rodriguez-Oroz MC, Rodriguez M, Guridi J, Mewes K, Chockkman V, Vitek J, DeLong MR, Obeso JA, The subthalamic nucleus in Parkinson's disease: somatotopic organization and physiological characteristics.Brain 124:Pt 9, 1777-90 (2001 Sep)
[1] Gradinaru V, Mogri M, Thompson KR, Henderson JM, Deisseroth K, Optical deconstruction of parkinsonian neural circuitry.Science 324:5925, 354-9 (2009 Apr 17)

{186}
hide / / print
ref: Guridi-2001.01 tags: STN DBS 2001 parkinsons hemiballismus Obeso date: 02-22-2012 15:14 gmt revision:8 [7] [6] [5] [4] [3] [2] [head]

PMID-11133783[0] The subthalamic nucleus, hemiballismus and Parkinson's disease: reappraisal of a neurosurgical dogma

  • Lesions of the globus pallidus, thalamus, as well as the STN can lead to hemiballismus
  • none-the-less, hemiballismus is a rather rare complication in STN DBS or lesion
  • GABA projection to the GPi is reduced in PD due to dopamine depletion
    • STN has projects glutamergic projections to GPi, so lesion would tend to worsten activity
    • STN also projects to the GPe, and lesioning it reduces hyper-activity there.
    • Therefore the balance of lesioning is to permit movements but not hemiballismus.
  • STN lesion in normal patients induces hemibalismus and chorea, but threshold for movements are raised with chronic dopamine depletion. cf {207}
  • Quality of life issues: perhaps everything has been learned already. {1124}

____References____

[0] Guridi J, Obeso JA, The subthalamic nucleus, hemiballismus and Parkinson's disease: reappraisal of a neurosurgical dogma.Brain 124:Pt 1, 5-19 (2001 Jan)

{1074}
hide / / print
ref: Gubellini-2009.09 tags: DBS PD 2009 review historical microstimulation ICMS chronaxie rheobase date: 02-22-2012 14:33 gmt revision:11 [10] [9] [8] [7] [6] [5] [head]

PMID-19559747[0] Deep brain stimulation in neurological diseases and experimental models: from molecule to complex behavior.

  • Wow, DBS has been used since the 1950s for localization of lesion targets; in the 1960's was discovered to alleviate tremor; 70s and 80s targeted at the cerebellum for treatimng movement disorders or epilepsy.
  • Extensive list of all the other studies & their stimulation protocols.
  • Large mylenated fibers have chronaxies ranging aruond 30-200 us, while cell bodies and dendrites this value is around 1-10ms. (Rank, 1975).
    • Lapique: minimum energy is a/b, where b is the rhreobase (the minimal electric current of infinite duration that results in an action potential), and chronaxie is the minimum time over which an electric current double the strength of the rheobase needs to be applied in order ti stimulate a nerve cell.
    • Q(t)t=U rh(1+t cht) \frac{Q(t)}{t} = U_{rh}(1 + \frac{t_ch}{t}) where U rhU_{rh} is the rheobase and t cht_{ch} is the chronaxie.
    • you can simplify this to: I th=I rh(1+t cht) I_{th} = I_{rh} (1 + \frac{t_{ch}}{t}) where I rhI_{rh} is the rheobase current and I thI_{th} is the threshold current (Irnich, 2002).
  • Measurements of chronaxie in VIM and GPi found values of 60-75us, hence DBS effects are likely mediated through the activation of afferent and efferent axons. (Holsheimer et al 2000a, 2000b)
    • In line with these findings, cortical stimulation also results in the activation of afferent and efferent axons (Nowak and Bullier, 1998a, 1998b PMID-9504844).
    • Ustim can result in cell body hyperpolarization coupled with action potential initiation in the axon (McIntyre and Grill, 1999; Nowak and Bullier 1998a b).
  • Stimulation depends on the direction of the electric field, obviously. When the axons and E\vec{E} are ||.
  • Acute stimulation is different from chronic DBS (as used in patients); it may be a mistake to extrapolate conclusions.
    • DBS electrodes become encapsulated, and current delivered hence decreases.
  • Strong placebo effect of just the DBS surgery.
    • Implantation of electrodes alone had therapeutic benefit in 6-mo trial. (Mann et al 2009).
  • mean lead impedance is 400-120 ohms in clinical DBS leads, PT-IR.
    • platinum is relatively non-toxic to the brain when compared to metals such as gold or rhodium.
  • If stimulation exceeds 30 uC/cm^2/phase, there is a risk of tissue damage. This equates to 30ma.
  • Stainless steel electrodes are damadged by days of in vivo stimulation -- metal ions are lost.
  • STN neurons spontaneously oscillate due to leak Ca currents and C-activated K channels.
  • STN DBS seems to disrupt abnormal synchronized activity recorded in the BG-thalamocortical loops in PD. (meta-analysis of several studies).
  • STN DBS seems to reduce FR in the SNr.
  • STN excitotoxic leasion in rats causes increased impulsivity, impaired accuracy, premature responses, and more attention to food reward location in rats.
    • There is a hyperdirect pathway from the medial prefrontal cortex to the STN; breaking this decreases attention and perseverance.
    • STN HFS sometimes induces impulsive behavior in humans, with which this is consistent. (This may be sequelae from levodopa treatment).
    • STN HFS often causes weight gain in patients. But it might be because they can eat more or are more 'motivated at life'.
    • Controlled studies in rats show that STN lesion does not effect quantity consumed, either food, ehanol, or cocaine.
      • Differential effect when the reward was food vs. cocaine -- the STN may modulate the reward system based on the nature of the reward.
  • Huh: HFS of the ZI (zona incerta) has been reported to be superior to STN HFS for improving contralateral parkinsonism in PD patients.
    • Could be current diffusion into the STN, however, as lesioning this structure in rats has less effect than lesioning STN.
    • See also {1098}.
  • Chronic GPi DBS does not allow reducing L-DOPA dosage, unlike STN stimulation, but it is a good treatment for dyskinesia.
  • VIM treatment is very effective for tremor, but it does not treat the other motor symptoms of PD. Furthermore, it wears off after a few years.
    • CM/Pf seems like an even better target (Center median / parafasicular complex of the thalamus -- see {1119}.
  • DBS in the PPN (pedunculo pontine nucleus, brainstem target of the BG) at 10 HZ induces a feeling of well-being , concomitant with a modest improvement in motor function; no effect at 80 Hz.
  • Dystonia: GPi is a efficacious target for DBS.
    • Full effect takes a year (!), suggesting that the effect is through reorganization of the BG / neuroplascticity.
  • ET : lesions of the VIM, STN, or cerebellum can reduce symptoms. DBS of the VIM, STN, or ZI all have been found effective.
  • Huntington's disease involves degeneration of the projection neurons from the caudate and putamen.
    • HD affects motor, cognitive, and psychiatric functioning.
  • Drug addiction: inactivating the Nucelus accumbens (NAc) may reduce motivation to obtain the drug, but it may also reduce the motivation to do anything (apathy).
  • GPi DBS also a target for reducing chorea.
  • STN DBS may worsen treatment-resistant-depression; this seen in an animal model, and anecdotally in humans with PD.
  • OCD can be treated with DBS through the internal capsule extending toward the NAc / ventral striatum.
    • side effects include hypomania or anxiety.
    • Alas there is no satisfactory animal model of OCD, which hampers research.

____References____

[0] Gubellini P, Salin P, Kerkerian-Le Goff L, Baunez C, Deep brain stimulation in neurological diseases and experimental models: from molecule to complex behavior.Prog Neurobiol 89:1, 79-123 (2009 Sep)

{369}
hide / / print
ref: notes-3000 tags: darpa 2007 misha report oscillations old notes date: 02-16-2012 17:50 gmt revision:7 [6] [5] [4] [3] [2] [1] [head]

We have found the following types of neurons during acute intraoperative recrodings from the subthalamic nucleus (STN) of awake parkinson's patients. During the surgeries the patients opened and closed their hand, instrumented through a virtual-reality data glove, in order to move a cursor to randomly presented targets in a 1-dimensional field.

It is thought that the STN controls the gating and timing of movements, and this gate/relay is implicated in the pathological oscillatory loop seen in Parkinson's disease. Therefore, it is not surprising that we have found cells that are tuned to both movement initiation and simultaneously tuned to oscillatory features of the behavior.

Below the probability of firing, (red = high, blue = low) is plotted vs time (x-axis) and y (target gating signal). The target gating signal is 1 400 ms around the appearance of a new target to the right of the cursor, -1 when the target appears to the left of the cursor, and 0 everywhere else; 1 corresponds to the top of the graph, and -1 to the bottom. This probability was caluclated in sliding 50ms lags across the x axis to illuminate any fixed temporal relationships; that is, if a neuron had a high probability of firing 500 ms before target appearance, the image would be red @ a lag of 0.5 (on the x axis) and 1 on the y axis. This method is a nonparametric, minimal-assumption way of looking at the correlations between behavior and neural firing. It is only assumed that the relationship between neural firing times and behavior is stationary, e.g. it does not evolve with time; this is a relatively safe assumption given the recording are generally short.

This plot shows a neuron which fires preferentially when a target appears and the patient moves to the left (again, in this graph: y = -1 indicates target appears to the left, + 1 target to the right, and 0 otherwise). Note that there is noticable oscillations, due to the fact that the patient's behavior was very periodic, with a period of around 2 seconds. The neuron was inhibited around the instant of target apperance, independent of direction, as indicated by the blue regions at y = -1 and 1 around lag 0.

This plot shows a neuron which is inhibited just before target apperance (in this plot, y = 1 400ms around target appearance, independent of direction). That is, the neuron stops firing upon sucessful completion of a movement. This neuron shows no pathological oscillatory tuning; therefore, it might be assumed that not all of the STN is incapacitated by Parkinson's disease.

Here is another example of a neuron that does not show oscillatory firing behavior. In this graph, y = 1 when the patient is opening or closing his hand (equivalently the cursor velocity exceeds a threshold); y = 0 otherwise. This neuron is therefore inhibited during periods of movement. Note that around a lag of 2.5 seconds, the neuron has a higher probability of firing (the red region), possibly indicating positive firing upon successful completion of a movement.

Another example of a neuron that is tuned to thresholded cursor velocity, though this time, the firing rate becomes positive just around the instant of movement. Note here there is evidence of highly periodic behavior, as seen in the green/yellow regions spaced about 1.6 seconds apart along y=1. The region at lag = 1.6 secons corresponds to the movement following target acquisition, hence exhibits a higher firing rate.

This neuron, like the one above, fires strongly whenever the hand moves. Interestingly, there appeared to be no directional information in either of these cells.

Finally, we discovered that there appears to be error-correlated firing within the STN. The neuron shown above is selectively inhibited around periods where the cursor and target positions differ. In the plot above y=1 indicates the absolute value of the target position - the cursor position exceeds a threshold of 20% of the total range (this is subtly different from the target apperance signal, as the patient can over shoot or under shoot the target position with the cursur, upon which this signal will be 1.

{1121}
hide / / print
ref: -0 tags: AAV2 parkinsons gene therapy date: 02-15-2012 17:45 gmt revision:4 [3] [2] [1] [0] [head]

PMID-20970382 Gene delivery of AAV2-neurturin for Parkinson's disease: a double-blind, randomised, controlled trial.

  • Dennis Turner on the list.
  • glial-cell derived neurotrophic factor (GDNF) protects dopamine neurons in in-vitro and animal models of Parkinson's disease.
  • Neurturin is a naturally occuring structural and functional analog of GDNF that improved dopaminergic activity in aged monkeys and also protected dopamine neurons in animal models of PD.
  • Results from open-label trial have shown benefits of continuous infusion of GDNF in the putamen in advanced PD patients.
  • Gene therapy of neuturin and GDNF provides long-term histological and behavioral benefits in primate models of PD. (5,9,16,17)
    • 5: PMID-17443702 Striatal delivery of CERE-120, an AAV2 vector encoding human neurturin, enhances activity of the dopaminergic nigrostriatal system in aged monkeys.
      • CERE-120 is an AAV2 vector.
      • Unilateral injection of vector; each monkey served as its own control.
      • Stronger hydroxylase immunoreactivity on injected side.
      • Therapeutic effects?
    • 9: PMID-17192932 Delivery of neurturin by AAV2 (CERE-120)-mediated gene transfer provides structural and functional neuroprotection and neurorestoration in MPTP-treated monkeys.
      • AAV2-NTN injected 4 days after MPTP rendered the monkeys hemiparkinsonian.
      • AAV2-NTN significantly improved MPTP-induced motor impairments by 80 to 90% starting at approximately month 4 and lasting until the end of the experiment (month 10).
    • 16: PMID-11052933 Neurodegeneration prevented by lentiviral vector delivery of GDNF in primate models of Parkinson's disease.
      • treatment with lentiviral delivery of glial cell line-derived neurotrophic factor (lenti-GDNF).
      • treatment applied 1 week after MPTP.
      • Reversed motor deficits in a hand-reach task.
      • Persistent gene expression out to 8 months.
      • Results look really good.
    • 17: PMID-15673656 Continuous low-level glial cell line-derived neurotrophic factor delivery using recombinant adeno-associated viral vectors provides neuroprotection and induces behavioral recovery in a primate model of Parkinson's disease.
      • GDNF treatment at low levels (0.04 ng/mg tissue).
      • 6-OHDA model.
      • The anatomical protection was accompanied by a complete attenuation of sensorimotor neglect, head position bias, and amphetamine-induced rotation. We conclude that when delivered continuously, a low level of GDNF in the striatum (approximately threefold above baseline) is sufficient to provide optimal functional outcome.
  • Open-label 12 month phase 1 trial of AAV2-neurturin in patients with advanced PD was safe, well tolerated, and associated with therapeutic benefits (19)
  • Histology was performed for two patients. Neurturin was strongly expressed around the injection site, but tyrosene hydroxlase staining was sparse.
  • Span of trial December 2006 - November 2008.
  • 58 patients.

{965}
hide / / print
ref: Teagarden-2007.03 tags: STN striatum operant conditioning behavior rats 2006 DBS date: 02-15-2012 03:36 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-17182916[0] Subthalamic and Striatal Neurons Concurrently Process Motor, Limbic, and Associative Information in Rats Performing an Operant Task

  • STN encodes behavioral events (reinforcement, nose poke, correct / incorrect trials). So does the striatum.
  • This study is rather nonspecific, but it makes sense that a conserved and well connected region is active during learning & general behavior.
    • That is, while the subthalamic nucleus is considered an output relay of the basal ganglia, more likely it operates in parallel to facilitate forms of learning; as such, responses are shown to rewards, cues, etc.

____References____

[0] Teagarden MA, Rebec GV, Subthalamic and striatal neurons concurrently process motor, limbic, and associative information in rats performing an operant task.J Neurophysiol 97:3, 2042-58 (2007 Mar)

{1109}
hide / / print
ref: -0 tags: Cogan 2008 electrodes recording stimulation date: 02-05-2012 00:21 gmt revision:0 [head]

PMID-18429704 Neural stimulation and recording electrodes.

  • Electrical stimulation of nerve tissue and recording of neural electrical activity are the basis of emerging prostheses and treatments for spinal cord injury, stroke, sensory deficits, and neurological disorders. An understanding of the electrochemical mechanisms underlying the behavior of neural stimulation and recording electrodes is important for the development of chronically implanted devices, particularly those employing large numbers of microelectrodes. For stimulation, materials that support charge injection by capacitive and faradaic mechanisms are available. These include titanium nitride, platinum, and iridium oxide, each with certain advantages and limitations. The use of charge-balanced waveforms and maximum electrochemical potential excursions as criteria for reversible charge injection with these electrode materials are described and critiqued. Techniques for characterizing electrochemical properties relevant to stimulation and recording are described with examples of differences in the in vitro and in vivo response of electrodes.

{172}
hide / / print
ref: Foffani-2004.07 tags: STN motor preparation human 2003 basal_ganglia DBS SMA date: 01-26-2012 17:23 gmt revision:3 [2] [1] [0] [head]

PMID-15249649 Involvement of the human subthalamic nucleus in movement preparation

  • STN receives large afferent from SMA, so it should be involved in movement planning.
  • the STN and nearby structures are active before self-paced movements in humans.
  • normal patients show a negative EEG movement-related potential (MRP) starting 1-2 seconds before the onset of self-paced movements.
  • STN also shows premovement negative MRP.
    • REquire very sensitive methods to record this MRP -- it's on the order of 1 uv.
  • the amplitude of the scalp MRP is reduced in parkinson's patients.
    • impairment of movement preparation in PD may be related to deficits in the SMA and M1, e.g. underactivity.
    • the MRP is normalized with the administration of levodopa.
  • MPTP monkeys have increased activity in the STN
  • examined the role of the STN in movement preparation and inhibition via MRP recorded from DBS electrodes in the STN + simultaneously recorded scalp electrodes.
  • their procedure has the leads externalized during the first week after surgery.

{170}
hide / / print
ref: Beurrier-1997.05 tags: STN stimulation hemiballismus 2007 DBS date: 01-26-2012 17:20 gmt revision:4 [3] [2] [1] [0] [head]

PMID-9189903[] Subthalamic stimulation elicits hemiballismus in normal monkey.

  • the effects of stimulation on normal waking primates has never been evaluated (doh!)
  • In the normal monkey, HFS appears reversibly to incapacitate the STN and allow the emergence of involuntary proximal displacements, due to disinhibition of the thalamo-cortical pathway
  • in MPTP-treated monkey HFS buffers STN activity and alleviates akinesia and rigitity by reducing inputs to the internal segment of the globus pallidus. (STN output is excitatory) (or so the theory at the time goes)
  • perhaps i will need to buy this article ;(

____References____

{1048}
hide / / print
ref: Kim-2009.04 tags: Utah ASIC recording 2009 date: 01-15-2012 22:08 gmt revision:1 [0] [head]

PMID-19067174[0] Integrated wireless neural interface based on the Utah electrode array

  • Describes their fully integrated 100 site Utah probe.
  • "A planar power receiving coil fabricated by patterning electroplated gold films on polyimide substrates was connected to the IC by using a custom metallized ceramic spacer and SnCu reflow soldering. The SnCu soldering was also used to assemble SMD capacitors on the UEA. "

____References____

[0] Kim S, Bhandari R, Klein M, Negi S, Rieth L, Tathireddy P, Toepper M, Oppermann H, Solzbacher F, Integrated wireless neural interface based on the Utah electrode array.Biomed Microdevices 11:2, 453-66 (2009 Apr)

{911}
hide / / print
ref: Ganguly-2009.07 tags: Ganguly Carmena 2009 stable neuroprosthetic BMI control learning kinarm date: 01-14-2012 21:07 gmt revision:4 [3] [2] [1] [0] [head]

PMID-19621062 Emergence of a stable cortical map for neuroprosthetic control.

  • Question: Are the neuronal adaptations evident in BMI control stable and stored like with skilled motor learning?
    • There is mixed evidence for stationary neuron -> behavior maps in motor cortex.
      • It remains unclear if the tuning relationship for M1 neurons are stable across time; if they are not stable, rather advanced adaptive algorithms will be required.
  • A stable representation did occur.
    • Small perturbations to the size of the neuronal ensemble or to the decoder could disrupt function.
    • Compare with {291} -- opposite result?
    • A second map could be learned after primary map was consolidated.
  • Used a Kinarm + Plexon, as usual.
    • Regressed linear decoder (Wiener filter) to shoulder and elbow angle.
  • Assessed waveform stability with PCA (+ amplitude) and ISI distribution (KS test).
  • Learning occurred over the course of 19 days; after about 8 days performance reached an asymptote.
    • Brain control trajectory to target became stereotyped over the course of training.
      • Stereotyped and curved -- they propose a balance of time to reach target and effort to enforce certain firing rate profiles.
    • Performance was good even at the beginning of a day -- hence motor maps could be recalled.
  • By analyzing neuron firing wrt idealized movement to target, the relationship between neuron & movement proved to be stable.
  • Tested to see if all neurons were required for accurate control by generating an online neuron dropping curve, in which a random # of units were omitted from the decoder.
    • Removal of 3 neurons (of 10 - 15) resulted in > 50% drop in accuracy.
  • Tried a shuffled decoder as well: this too could be learned in 3-8 days.
    • Shuffling was applied by permuting the neurons-to-lags mapping. Eg. the timecourse of the lags was not changed.
  • Also tried retraining the decoder (using manual control on a new day) -- performance dropped, then rapidly recovered when the original fixed decoder was reinstated.
    • This suggests that small but significant changes in the model weights (they do not analyze what) are sufficient for preventing an established cortical map from being transformed to a reliable control signal.
  • A fair bit of effort was put into making & correcting tuning curves, which is problematic as these are mostly determined by the decoder
    • Better idea would be to analyze the variance / noise properties wrt cursor trajectory?
  • Performance was about the same for smaller (10-15) and larger (41) unit ensembles.

{779}
hide / / print
ref: Song-2005.06 tags: recording wireless silicon utah probe Donoghue 2005 date: 01-08-2012 23:24 gmt revision:3 [2] [1] [0] [head]

PMID-16003903[0] Development of a chipscale integrated microelectrode/microelectronic device for brain implantable neuroengineering applications.

-- second from this

  • They have mated a 16-channel silicon microprobe to a low-power (50uW/channel) VLSI chip, including a CMOS amplifier.
    • Epoxy ball-bond.
    • 7mW total power.
  • Suggest photovoltaic power using GaAs/AlGaAs photodiodes. 3 in series yielding 3V at about 20% efficiency. Not bad! Then they can use the fiber to get data out, too.

____References____

[0] Song YK, Patterson WR, Bull CW, Beals J, Hwang N, Deangelis AP, Lay C, McKay JL, Nurmikko AV, Fellows MR, Simeral JD, Donoghue JP, Connors BW, Development of a chipscale integrated microelectrode/microelectronic device for brain implantable neuroengineering applications.IEEE Trans Neural Syst Rehabil Eng 13:2, 220-6 (2005 Jun)

{318}
hide / / print
ref: Carmena-2003.11 tags: Carmena nicolelis BMI learning 2003 date: 01-08-2012 18:53 gmt revision:5 [4] [3] [2] [1] [0] [head]

PMID-14624244[0] Learning to control a brain-machine interface for reaching and grasping by primates.

  • strong focus on learning & reorganization.
  • Jose's first main paper.
  • focuses on two engineering / scientific questions: what signal to use, and how much of it, and from where.
    • As for where, of course we suggest that the representation is distributed.
  • Quality of predictions: gripping force > hand velocity > hand position.
  • Showed silent EMGs during BMI control.
  • Put a robot in the feedback path; this ammounted for some nonlinearities + 60-90ms delay.
  • Predictions follow anatomical expectation:
    • M1 (33-56 cells) predicts 73% variance for hand pos, 66% velocity, 83% for gripping force .
    • SMA (16-19 cells) 51% position, 51% velocity, 19% gripping force.
    • They need a table for this shiz.
  • Relatively high-quality predictions. (When I initially looked at the data, I was frustrated with the noise!)
  • Learning was associated with increased contribution of single units.
    • appeared to be more 'learning' in SMA.
    • Training on a position model seemed to increase the ctx representation of hand position.
  • changes between pole control and brain control:
    • 68% of of sampled neurons showed reduced tuning in BCWOH
    • 14% no change
    • 18% enhanced tuning.
  • Directional tuning curves clustered in a band during brain control -- neurons clustering around the first PC?
    • All cortical areas tested showed increases in correlated firing -- arousal?
    • this puts some movements into the nullspace of the Wiener matrix. Or does it? should have had the monkey make stereotyped movements to dissociate movement directions.
  • Knocks {334} in that:
    • preferred directions were derived not from actual movements, but from firing rates during target appearance time windows.
    • tuning strength could have increased simple because the movements became straighter with practice.
  • From Fetz, {329}: Interestingly, the conversion parameters obtained for one set of trials provided increasingly poor predictions of future responses, indicating a source of drift over tens of minutes in the open-loop condition. This problem was alleviated when the monkeys observed the consequences of their neural activity in ‘real time’ and could optimize cell activity to achieve the desired goal under ‘closed-loop’ conditions.

____References____

{956}
hide / / print
ref: Fetz-1992 tags: Fetz 1992 Motor control M1 PV date: 01-06-2012 18:13 gmt revision:1 [0] [head]

bibtex: Fetz-1992 Are movement parameters recognizably coded in the activity of single neurons

  • Fetz seems to think that many of the reported correlations or specializations, whether in terms of latency or tuning, are largely a result of observer bias (e.g. to ignore non-obviously tuned cells), and that both simple and complex tuning to motor parameters can be found throughout the motor and premotor cortices.
    • Plus, evidence seems to point to the fact that most things happen simultaneously across multiple areas.
  • Shows that a neural-network model of M1 has complicated and interesting tuning within the hidden network, which he thinks is consistent with the observations.
  • Nice: "This suggests that the search for explicit coding may be diverting us from understanding distributed neural mechanisms that operate without literal representations. "

{348}
hide / / print
ref: notes-0 tags: clementine operant conditioning 041707 pyramidal tract tlh24 date: 01-06-2012 03:12 gmt revision:4 [3] [2] [1] [0] [head]

It appears that operant/feedback training of one neuron (channel 29, in SMA region) works fine (not great, but fine). In the experiment performed prior to visiting Seattle, on April 10 2007, I was not convinced that the neuron was controlling anything. Now, it is apparent that the monkey has some clue as to what he is doing. Today I made a simple change: I made the filtering function sum (all spikes) 1/12 * x*(x-1)^2, where x = time - time_of_spike. In comparison to a butterworth filter, this has no rebound oscillation & makes the estimation of firing rate much more transparent. It averages over approximately 500ms ~= lowcut of 1.5hz? I see no reason to change this filtering function much, as it works fine. Spikes were binned at 100hz as input to this function, but that should be equivalent to binning at 1khz etc.

Next time, i want to do 2d, where channel 62 controls the Y-axis. really should try to determine the approximate tunings of these cells. I'm somewhat concerned as this channel seems to have a much lower mean firing rate than channel 29. According to the literature, PTNs have high firing rates and strong tuning...

for reference, here is the channel used for the one-neuron BMI, recorded April 10. It has not changed much in the last 7 days.

{901}
hide / / print
ref: Zacksenhouse-2007.07 tags: Zacksenhouse 2007 Odoherty Nicolelis cortical adaptation BMI date: 01-06-2012 03:10 gmt revision:3 [2] [1] [0] [head]

PMID-17637835[0] Cortical modulations increase in early sessions with brain-machine interface.

  • "we demonstrate that the modulations of the firing-rates of cortical neurons increased abruptly after the monkeys started operating the BMI"
    • My hypothesis: is this like LMAN? Injection of noise for the purpose of exploration?
    • Their hypothesis: we are listening to the noise or effect of increased processing / congnitive load.
    • Alternative: decreased feedback / scrabled feedback makes the individual control signals themselves less controlled.
  • Describes spikes as inhomogeneous poisson processes, and breaks things down thusly.
  • Also develop a parametric model of neuronal firing based on tuning to movement, including velocity and acceleration.
  • Fano factor of recorded neurons increased during BCWH & BCWOH.
  • Percent overall modulation (POM) higher in brain control. That is, the variance explained not by the inhomogeneous poisson process, but rather by firing rate variations.
    • "[T]he ensemble-POM increased mainly due to an increase in the variance of the spike-count, which was not matched by the change in the mean spike-count."
  • Figure 6 is pretty convincing, actually.
  • PVM (percent velocity modulation) correlates strongly with POM, but with a fractional slope, indicating that veolocity tuning accounts for only a fraction of the variance.
    • "Since the increase in POM was not matched by increasing PVM or PKM, the higher neuronal rate modulations observed during brain control cannot be explained only by increased modulations due to the kinematics of the movement."

____References____

[0] Zacksenhouse M, Lebedev MA, Carmena JM, O'Doherty JE, Henriquez C, Nicolelis MA, Cortical modulations increase in early sessions with brain-machine interface.PLoS One 2:7, e619 (2007 Jul 18)

{368}
hide / / print
ref: thesis-0 tags: clementine 051607 operant conditioning tlh24 date: 01-06-2012 03:09 gmt revision:1 [0] [head]

the cells were, basically, as usual for today. did 1-d BMI on channel 29; worked somewhat (nothing dramatic; mk is out of practice?)

{301}
hide / / print
ref: thesis-0 tags: clementine Kalman wiener tlh24 date: 01-06-2012 03:08 gmt revision:3 [2] [1] [0] [head]

040507. wiener pred. same deal as {262}

kalman fit/pred.

per-unit and channel aggregate SNR summary

    unit     chan       lag       snr       behav var
    1.0000   69.0000    1.0000    1.1159    2.0000
    1.0000   58.0000    1.0000    1.1074    6.0000
    2.0000   44.0000    2.0000    1.1040    2.0000
    2.0000   44.0000    1.0000    1.0953    2.0000
    2.0000   93.0000    1.0000    1.0868    3.0000
    2.0000   64.0000         0    1.0728    3.0000
    1.0000   69.0000    2.0000    1.0698    2.0000
    1.0000   32.0000         0    1.0684    3.0000
    2.0000   44.0000         0    1.0634    8.0000
    1.0000   58.0000         0    1.0613    6.0000
    1.0000   33.0000    1.0000    1.0594    1.0000
    2.0000   93.0000    3.0000    1.0523    3.0000
    1.0000   63.0000         0    1.0507    3.0000
    1.0000   67.0000    1.0000    1.0490    5.0000
    1.0000   47.0000         0    1.0489    3.0000
    1.0000   12.0000    4.0000    1.0472    3.0000
    2.0000   93.0000    2.0000    1.0460    3.0000
    1.0000   24.0000         0    1.0459    3.0000
    1.0000   42.0000    1.0000    1.0447    6.0000
    1.0000   24.0000    1.0000    1.0440    3.0000
    1.0000   69.0000    3.0000    1.0431    2.0000
    2.0000   60.0000         0    1.0429    5.0000
    1.0000   61.0000         0    1.0410    4.0000
    1.0000   12.0000    1.0000    1.0400    1.0000
    1.0000   32.0000    3.0000    1.0395    3.0000
    1.0000    8.0000    1.0000    1.0387    1.0000
    1.0000   33.0000         0    1.0386   11.0000
    1.0000         0    1.0000    1.0383    4.0000
    2.0000   77.0000    2.0000    1.0383    1.0000
    1.0000   47.0000    1.0000    1.0382    3.0000
    2.0000   60.0000    1.0000    1.0376   10.0000
    2.0000   77.0000    1.0000    1.0375    1.0000
    1.0000   28.0000    1.0000    1.0374    1.0000
    1.0000   69.0000    5.0000    1.0359    3.0000
    1.0000   42.0000         0    1.0358    3.0000
    1.0000    8.0000         0    1.0357    3.0000
    1.0000   63.0000    3.0000    1.0357    3.0000
    2.0000   68.0000    1.0000    1.0348    1.0000
    1.0000   51.0000         0    1.0343    3.0000
    1.0000   30.0000    1.0000    1.0341    1.0000
    1.0000   24.0000    2.0000    1.0341    3.0000
    2.0000   93.0000    5.0000    1.0340    3.0000
    1.0000   63.0000    4.0000    1.0338    3.0000
    1.0000   63.0000    2.0000    1.0337    3.0000
    1.0000   12.0000    2.0000    1.0329    1.0000
    2.0000   23.0000    1.0000    1.0325    1.0000
    1.0000   46.0000    1.0000    1.0324    2.0000
    1.0000   28.0000         0    1.0323    1.0000
    2.0000   93.0000    4.0000    1.0321    3.0000
    1.0000   58.0000    3.0000    1.0316    6.0000
    1.0000   47.0000    2.0000    1.0314    6.0000
    1.0000   48.0000         0    1.0311    4.0000
    1.0000   12.0000    3.0000    1.0310    3.0000
    1.0000   12.0000         0    1.0309    3.0000
    1.0000   48.0000    1.0000    1.0303   11.0000
    1.0000   28.0000    2.0000    1.0300    1.0000
    2.0000   60.0000    2.0000    1.0294   10.0000
    1.0000   46.0000         0    1.0293    8.0000
    1.0000   49.0000         0    1.0291    3.0000
    1.0000   24.0000    3.0000    1.0286    1.0000
    2.0000   77.0000    3.0000    1.0282    3.0000
    1.0000    8.0000    2.0000    1.0282    1.0000
    2.0000   15.0000    1.0000    1.0281    3.0000
    2.0000   68.0000    2.0000    1.0278    1.0000
    2.0000   23.0000         0    1.0273    1.0000
    1.0000  112.0000    1.0000    1.0261    7.0000
    1.0000   69.0000    4.0000    1.0258    3.0000
    2.0000   92.0000    3.0000    1.0244    3.0000
    2.0000   42.0000    1.0000    1.0244   11.0000
    1.0000   58.0000    2.0000    1.0238    3.0000
    1.0000   61.0000    1.0000    1.0234    7.0000
    1.0000   32.0000    4.0000    1.0232    3.0000
    1.0000   33.0000    2.0000    1.0231    1.0000
    1.0000   30.0000    4.0000    1.0231    3.0000
    1.0000   46.0000    2.0000    1.0227    2.0000
    1.0000   30.0000    3.0000    1.0226    3.0000
    1.0000   45.0000         0    1.0225    3.0000
    1.0000   60.0000         0    1.0225    3.0000
    2.0000   84.0000    5.0000    1.0222    3.0000
    1.0000   32.0000    1.0000    1.0221    1.0000
    1.0000   24.0000    4.0000    1.0220    1.0000
    1.0000   28.0000    3.0000    1.0219    1.0000
    1.0000   64.0000    1.0000    1.0216    4.0000
    2.0000   84.0000    1.0000    1.0215    3.0000
    1.0000   30.0000         0    1.0212    3.0000
    2.0000   77.0000    5.0000    1.0211    3.0000
    1.0000   63.0000    1.0000    1.0210    3.0000
    1.0000   33.0000    4.0000    1.0209    1.0000
    1.0000    7.0000    1.0000    1.0209    3.0000
    2.0000   35.0000         0    1.0202    3.0000

{349}
hide / / print
ref: thesis-0 tags: clementine 042007 operant conditioning biofeedback tlh24 date: 01-06-2012 03:08 gmt revision:4 [3] [2] [1] [0] [head]

channel 29 controlled the X direction:

channel 81, the Y direction (this one was very highly modulated, and the monkey could get to a high rate ~60Hz. note that both units are sorted as one -- I ought to do the same on the other channels from now on, as this was rather predictive (this is duplicating Debbie Won's results):

However, when I ran a wiener filter on the binned spike rates (this is not the rates as estimated through the polynomial filter), ch 81 was most predictive for target X position; ch 29, Y target position (?). This is in agreement with population-wide predictions of target position: target X was predicted with low fidelity (1.12; cc = 0.35 or so); target Y was, apparently, unpredicted. I don't understand why this is, as I trained the monkey for 1/2 hour on just the opposite. Actually this is because the targets were not in a random sequence - they were in a CCW sequence, hence the neuronal activity was correlated to the last target, hence ch 81 to target X!

for reference, here is the ouput of bmi_sql:

order of columns: unit,channel, lag, snr, variable

ans =

    1.0000   80.0000    5.0000    1.0909    7.0000
    1.0000   80.0000    4.0000    1.0705    7.0000
    1.0000   80.0000    3.0000    1.0575    7.0000
    1.0000   80.0000    2.0000    1.0485    7.0000
    1.0000   80.0000    1.0000    1.0402    7.0000
    1.0000   28.0000    4.0000    1.0318    8.0000
    1.0000   76.0000    2.0000    1.0238   11.0000
    1.0000   76.0000    5.0000    1.0225   11.0000
    1.0000   17.0000         0    1.0209   11.0000
    1.0000   63.0000    3.0000    1.0202    8.0000

movies of the performance are here:

{351}
hide / / print
ref: thesis-0 tags: clementine 042107 operant conditioning tlh24 date: 01-06-2012 03:08 gmt revision:5 [4] [3] [2] [1] [0] [head]

I tried to train Clem, once again, to do 2d BMI, this time with channel 69 for X and channel 71 for Y. X worked rather well, to a point - he realized that he could control it with left shoulder contractions, and did so (did not get a video of this). I did, however, get a video of the game, which is here:

Y training/performance was abysmal and hence did not try 2D control. Channel 71 would become silent whenever he began to pay attention; I'm not sure why. It would fire vigorously when he turned around and rested; the unit had a high firing rate at rest. I did not get a pic of the sortclient for today, but ch 29 was there as usual (though i did not use it) & channel 71 had the characteristic sharp V shape; perhaps it was an interneuron?? I don't know.

anyway, the data is in SQL on hardm.ath.cx. (the real proof is in the pudding, of course).

we really need to put the BMI game in his home cage, so motivation is not such a large issue

{222}
hide / / print
ref: neuro notes-0 tags: clementine thesis electrophysiology fit predictions tlh24 date: 01-06-2012 03:07 gmt revision:4 [3] [2] [1] [0] [head]

ok, so i fit all timestamps from clem022007001 & timarm_log_070220_173947_k.mat to clementine's behavior, and got relatively low SNR for almost everything - despite the fact that I am most likely overfitting. (bin size = 7802 x 1491) the offset is calibrated @ 2587 ms + 50 to center the juice artifact in the first bin. There are 10 lags. There are 21 sorted units.

same thing, but with only the sorted units. juice prediction is, of course, worse.

now, for file clem022007002 & timarm_log_070220_175636_k.mat. first the unsorted:

and the sorted:

{249}
hide / / print
ref: notes-0 tags: sorting SNR correlation coefficient expectation maximization tlh24 date: 01-06-2012 03:07 gmt revision:5 [4] [3] [2] [1] [0] [head]

Description: red is the per-channel cross-validated correlation coeifficent of prediction. Blue is the corresponding number of clusters that the unit was sorted into, divided by 10 to fit on the same axis. The variable being predicted is cartesian X position. note 32 channels were dead (from PP). The last four (most rpedictive) channels were: 71 (1 unit), 64 (5 units), 73 (6 units), 67 (1 unit). data from sql entry: clem 2007-03-08 18:59:27 timarm_log_20070308_185706.out ;Looks like this data came from PMD region.

Description: same as above, but for the y-axis.

Description: same as above, but for the z-axis.

Conclusion: sorting seems to matter & have a non-negligible positive effect on predictive ability.

{262}
hide / / print
ref: research-0 tags: clementine tlh24 Kalman thesis date: 01-06-2012 03:07 gmt revision:3 [2] [1] [0] [head]

clementine, 040207, Miguel's sorting. top 200 lags selected via bmisql.m , decent SNR on all channels but I had to z-score the state and measurement matricies.

-- standard wiener

-- linear kalman.

-- associated behavior

{175}
hide / / print
ref: BMI notes-0 tags: spike filtering rate_estimation BME 265 Henriquez date: 01-06-2012 03:06 gmt revision:1 [0] [head]

http://hardm.ath.cx:88/pdf/BME265_final.pdf

{949}
hide / / print
ref: Velliste-2008.06 tags: Schwartz 2008 Velliste BMI feeding population vector date: 01-06-2012 00:19 gmt revision:1 [0] [head]

PMID-18509337[0] Cortical control of a prosthetic arm for self-feeding

  • Idea: move BMI into robotic control.
  • population vector control, which has been shown to be inferior to the Wiener filter.
  • 112 units for control in one monkey. 2 monkeys used.
  • 4D control -- x, y, z, gripper.
  • 1064 trials over 13 days, average success rate of 78%
  • Gripper opened as the arm returned to mouth. Works b/c marshmallows are sticky.

____References____

[0] Velliste M, Perel S, Spalding MC, Whitford AS, Schwartz AB, Cortical control of a prosthetic arm for self-feeding.Nature 453:7198, 1098-101 (2008 Jun 19)

{210}
hide / / print
ref: notes-2007 tags: clementine BMI robot kinarm timarm 032807 date: 01-06-2012 00:07 gmt revision:14 [13] [12] [11] [10] [9] [8] [head]

  1. http://m8ta.com/tim/clementine.MOV -- opens with totem, MJPG compressor.
  2. http://m8ta.com/tim/timarm_servocontroller.JPG
  3. http://m8ta.com/tim/images/spikeInformation_shuffled.jpg
    1. shuffled information distribution -- high significance level ;)
  4. kinarm.
    1. http://www.hardcarve.com/tim/kinarm.JPG
    2. http://www.hardcarve.com/tim/kinarm2.JPG
    3. http://www.hardcarve.com/tim/kinarm3.JPG
  5. robot svg or timarm png
    1. http://www.hardcarve.com/tim/timarm/timarm_side.jpg
    2. http://m8ta.com/tim/robotPulleyDetail.png
  6. bmi predictions clem 032807
      1. x & y predictions
      1. x & y predictions
      1. z velocity predictions - pretty darn good, snr 2
    1. Movie of the day: http://m8ta.com/tim/clem032807_3dBMI.MPG
      1. cells for that day - 40 in all

{376}
hide / / print
ref: Darmanjian-2005.03 tags: recording wifi 802.11 DSP BMI Principe date: 01-03-2012 02:13 gmt revision:2 [1] [0] [head]

IEEE-1419566 (pdf) A Portable Wireless DSP System for a Brain Machine Interface

  • 1400Mw (yuck!!), large design, PCMCIA 802.11 card @ 1.8 Mbps, external SRAM for models
  • implemented LMS and as expected it's faster on the Texas Instruments C33 floating-point DSP.

____References____

Darmanjian, S. and Morrison, S. and Dang, B. and Gugel, K. and Principe, J. Neural Engineering, 2005. Conference Proceedings. 2nd International IEEE EMBS Conference on 112 -115 (2005)

{894}
hide / / print
ref: Bonfanti-2010.09 tags: neural recording wireless manchester 2010 Italy date: 01-03-2012 01:02 gmt revision:2 [1] [0] [head]

IEEE-5619710 (pdf) A Multi-Channel Low-Power IC for Neural Spike Recording with Data Compression and Narrowband 400-MHz MC-FSK Wireless Transmission

  • Good 64-channel wireless neurochip with LNA, variable gain and filtering, spike extraction.
  • ~300uW/channel realized.
  • 2.7x3.1mm

____References____

Bonfanti, A. and Ceravolo, M. and Zambra, G. and Gusmeroli, R. and Borghi, T. and Spinelli, A.S. and Lacaita, A.L. ESSCIRC, 2010 Proceedings of the 330 -333 (2010)

{741}
hide / / print
ref: Sodagar-2006.31 tags: Najafi michigan probe silicon recording 2006 date: 01-03-2012 00:56 gmt revision:5 [4] [3] [2] [1] [0] [head]

IEEE-4463150 (pdf) A neural signal processor for an implantable multi-channel cortical recording microsystem

  • Full 64 ch NPU (neural processing unit). The 'competition'.
    • Scan mode: all 64 channels are searched for the occurence of neural spikes. Addresses with neural activity are sorted, packed, and sent to the outside world.
      • Each channel can be individually set to +, -, or +- spikes. (no templates).
    • monitor mode: 2 channels of broadband transmission.
  • ref [3] claims 100 channels integrated.
  • inductive bidirectional wireless link.
  • Hierarchical design: 64 channels = 2 32 channel master/slave NPUs, each 4 8-channel modules.
  • External 8-bit A/D converter.
  • One 32-ch NPU in 0.5um AMI N-well CMOS process, 3.5mm x 2.7mm.
  • channel scan rate 64ksample/sec; 64 kspikes/sec, typical 8:1 data compression.
  • 2mbps output rate.
  • see also {393} and {149} - they report the same results, perhaps in more detail.

____References____

Sodagar, A.M. and Wise, K.D. and Najafi, K. Engineering in Medicine and Biology Society, 2006. EMBS '06. 28th Annual International Conference of the IEEE 5900 -5903 (2006)

{983}
hide / / print
ref: ODoherty-2011.1 tags: nicolelis odoherty nicolelis 2011 active tactile BMBI stimulation ICMS unscented Kalman filter date: 01-01-2012 18:27 gmt revision:3 [2] [1] [0] [head]

PMID-21976021[0] Active tactile exploration using a brain-machine-brain interface.

  • Tricky part was the temporal interleaving. 50ms stim / 50ms record.
    • No proof a priori as S1 stim could affect M1 processing.
  • Real perception, as the stimulation resulted from motor commands (through a BMI).
  • RAT = rewarded ICMS (200Hs pulses)
  • UAT = unrewarded ICMS, 400Hs, skip every 100ms.
  • NAT = no ICMS.
  • So short. damn you, nature.

____References____

[0] O'Doherty JE, Lebedev MA, Ifft PJ, Zhuang KZ, Shokur S, Bleuler H, Nicolelis MA, Active tactile exploration using a brain-machine-brain interface.Nature 479:7372, 228-31 (2011 Oct 5)

{291}
hide / / print
ref: Carmena-2005.11 tags: carmena BMI nicolelis single-unit variability 2005 date: 01-01-2012 17:31 gmt revision:2 [1] [0] [head]

PMID-16291944[0] Stable ensemble performance with single-neuron variability during reaching movements in primates.

  • correlation between the firing of single neurons and movement parameters was nonstationary over 30-60 minute recording sessions.
  • yet! you could get stable prediction of arm movements, suggesting that movement parameters are redundantly encoded.
  • this, in turn, implies that you do not need a stable recorded population for good predictions.
  • suggest that the variance itself could be a means of neuronal 'computation' or exploration based on perturbations.
    • later Carmena papers do not mention this.

____References____

{971}
hide / / print
ref: Vaadia-2009.09 tags: BMI Vaadia 2009 date: 12-28-2011 20:39 gmt revision:2 [1] [0] [head]

PMID-20228862[0] Grand Challenges of Brain Computer Interfaces in the Years to Come

  • Problem 1: If you have no theory of mind, you just keep making a series of measurements.
  • EEG is like listening to lectures of millions of people ... simultaneously.
  • Single unit recordings is like probing a microchip's individual wires and trying to figure out what it's doing (this is not a good analogy, though -- brains are far more robust to part failure than a computer).
  • References Todorov 2004 PMID-15332089[1] Wolpert and Ghahramani 2000: Sensorimotor control.
  • Problem 2: noisy measurements.
    • Might be the brains problem, not us: neuronal interactions modify rapidly during sensorimotor learning. Jarosiewicz et al 2008. PMID-19047633[2]
    • Claim to have a system that learns control within 1-2 minutes or '10 seconds', coadaptively. Shpigelman 2009. bibtex:Shpigelman-2009
  • In drug resistant focal epilepsy, not only were substantial reductions in seizures reported, but also large gains in IQ and cognitive functioning were demonstrated (Kotchoubey 2001, Strehl et al 2005) after training of slow cortical potential control. Better ref: PMID-10457815[3]
  • Buch et al 2008 Demonstrated MEG BMI control. PMID-18258825[4]
  • Even with sophisticated classification solutions, EEG cannot provide much better than 2D control (Birbaumer 1990). PMID-2404287[5]
  • Ref Moritz [6]
  • Supposes that nanotechnology may ultimately find a solution -- inert nanoprobes that measure activity and transmit a compressed version.

____References____

[0] Vaadia E, Birbaumer N, Grand challenges of brain computer interfaces in the years to come.Front Neurosci 3:2, 151-4 (2009 Sep 15)
[1] Todorov E, Optimality principles in sensorimotor control.Nat Neurosci 7:9, 907-15 (2004 Sep)
[2] Jarosiewicz B, Chase SM, Fraser GW, Velliste M, Kass RE, Schwartz AB, Functional network reorganization during learning in a brain-computer interface paradigm.Proc Natl Acad Sci U S A 105:49, 19486-91 (2008 Dec 9)
[3] Thompson L, Thompson M, Neurofeedback combined with training in metacognitive strategies: effectiveness in students with ADD.Appl Psychophysiol Biofeedback 23:4, 243-63 (1998 Dec)
[4] Buch E, Weber C, Cohen LG, Braun C, Dimyan MA, Ard T, Mellinger J, Caria A, Soekadar S, Fourkas A, Birbaumer N, Think to move: a neuromagnetic brain-computer interface (BCI) system for chronic stroke.Stroke 39:3, 910-7 (2008 Mar)
[5] Birbaumer N, Elbert T, Canavan AG, Rockstroh B, Slow potentials of the cerebral cortex and behavior.Physiol Rev 70:1, 1-41 (1990 Jan)
[6] Moritz CT, Perlmutter SI, Fetz EE, Direct control of paralysed muscles by cortical neurons.Nature 456:7222, 639-42 (2008 Dec 4)

{955}
hide / / print
ref: -0 tags: todorov R2 M1 PV tuning bias decision boundaries controversy date: 12-22-2011 22:52 gmt revision:1 [0] [head]

PMID-11017160 Reply to One motor cortex, two different views

{950}
hide / / print
ref: -0 tags: Todorov motor control models 2000 date: 12-22-2011 21:18 gmt revision:3 [2] [1] [0] [head]

PMID-10725930 Direct cortical control of muscle activation in voluntary arm movements: a model.

  • Argues that the observed high-level control of parameters (movement direction) is inconsistent with demonstrated low-level control (control of individual muscles / muscle groups, as revealed by STA [5] or force production [3]), but this inconsistency is false: the principle of low level control is correct, and high level control appears due to properties of the musculoskeletal system.
  • "Yet the same cells that encode hand velocity in movement tasks can also encode the forces exerted against external objects in both movement and isometric tasks [9,10].
  • The following other correlations have been observed:
    • arm position [11]
    • acceleration [12]
    • movement preparation [13]
    • target position [14]
    • distance to target [15]
    • overall trajectory [16]
    • muscle coactivation [17]
    • serial order [18]
    • visual target position [19]
    • joint configuration [20]
    • instantaneous movement curvature [7]
    • time from movement onset [15]
  • although these models can fit the data well, they leave a crucial question unanswered, namely, how such a mixed signal can be useful for generating motor behavior.
    • What? No! The diversity of voices gives rise to robust, dynamic computation. I think this is what Miguel has written about, will need to find a reference.
  • Anyway, all the motor parameters are related by the laws of physics -- the actual dimensionality of real reaches is relatively low.
  • His model: muscle activity simply reflects M1 PTN activity.
  • If you include real muscle parameters, a lot of the observed correlations make sense: muscle force depends not only on activation, but also on muscle length and rate of change of length.
  • In this scientific problem, the output (motor behavior) specified by the motor task is easily measured, and the input (M1 firing) must be explained.
    • Due to the many-to-one mapping, there is a large null-space of the inverse transform, so individual neurons cannot be predicted. Hence focus on population vector average.
  • Cosine tuning is the only activation pattern that minimizes neuromotor noise (derived in methods, Parseval's theorem)). Hence he uses force, velocity, and displacement tuning for his M1 cells.
  • Activity of M1 cells is constrained in endpoint space, hence depends only on behavioral parameters.
    • The muscles were "integrated out".
  • Using his equation, it is clear that for an isometric task, M1 activity is cosine tuned to force direction and magnitude -- x(t) is constant.
  • For hand kinematics in the physiological range with an experimentally measured inertia-to-damping ratio, the damping compensation signal dominates the acceleration signal.
    • Hence population x˙(t)\propto \dot x(t)
    • Muscle damping is asymmetric: predominant during shortening.
  • The population vector ... is equal not to the movement direction or velocity, but instead to the particular sum of position, velocity, acceleration, and force signals in eq. 1
  • PV reconstruction fails when movement and force direction are varied independently. [28]
  • Fig 4. Schwartz' drawing task -- {951} -- and shows how curvature, naturalistic velocity profiles, the resultant accelerations, and leading neuronal firing interact to distort the decoded PV.
    • Explains why, when assuming PV tuning, there seems to be variable M1-to-movement delay. At high curvature PV tuning can apprently lag movement. Impossible!
  • Fig 5 reproduces [21]
    • Mean firing rate (mfr, used to derive the poisson process spike times) and r^2 based classification remarkably different -- smoothing + square root biases toward finding direction-tuned cells.
    • Plus, as P, V, and A are all linearly related, a sum of the 3 is closer to D than any of the three.
    • "Such biases raise the important question of how one can determine what an individual neuron controls"
  • PV reversals occur when the force/acceleration term exceeds the velocity scaling term -- which is 'equivalent' to the triphasic burst pattern observed in EMG. Ergo monkeys should be trained to make faster movements.
  • The structure of your model -- for example firingrate=b 0+b xX+b yY+b mMfiringrate = b_0 + b_x X + b_y Y + b_m M biases analysis for direction, not magnitude; correct model is firingrate=b 0+b xmXM+b ymYM firingrate = b_0 + b_{xm}XM + b_{ym}YM -- multiplicative.
  • "Most of these puzzling phenomena arise from the feedforward control of muscle viscoelasticity."
  • Implicit assumption is that for the simple, overtrained, unperturbed movements typically studied, feedforward neural control is quite accurate. When you get spinal reflexes involved things may change. Likewise for projections from the red nucleus.

{935}
hide / / print
ref: Georgopoulos-1982.11 tags: Georgopoulos 1982 motor tuning cortex M1 population vector date: 12-19-2011 23:52 gmt revision:1 [0] [head]

PMID-7143039 On the relations between the direction of two-dimensional arm movements and cell discharge in primate motor cortex.

  • eight directions 45deg intervals, 2D joystick, frictionless, LED tarkets in a blocked randomized experimental design.
    • MK made simultaneous saccades; saccade latency 150-170ms.
      • some motor cells responded to visual movement.
    • EMG activity began ~80ms before movement.
    • monkeys used both arms.
  • bell-shaped or cosine tuning in 75% of the cells.
    • This has also been described in the saccade system in the paramedian pontine reticular formation (Henn and Cohen 1976), the mesencelphatic reticular formation (Buttner eta la 1977) and the internal medullary lamina of the thalamus (Schlag and Schlag-Ney 1977)
  • cells tended to cluster by tuning in depth.
  • cells tended to respond to movement & small corrections to movement, but did not necessarily respond to non-task related movement. "Yet these same cells were frequently silent during other movements which also involved contraction of the same muscles [as used in the task]"
  • cell discharge was much stronger during active movements than during passive manipulations.
  • 64% of cells were activated before the earliest EMG changes; 87% before the onset of movement.
  • The famous one, where the population vector was formalized / conceived / validated.
  • most neurons begin firing ~ 100ms before movement begins.
  • useda PDP11/20 minicomputer to control the LEDs & data recording.
  • Thach 1978 -- approxmately equal proportions of motor cortical cells were related to muscle activity, hans position, and direction of intended movement Thach 1978) PMID-96223
  • single electrode Pt/Ir recording 2-3Mohm; recordings made for 6-7 hours.
  • cite georgopoulos 1983 -- they propose distributed population coding.
  • point out that the central problem -- upon which some progress has been made - is the translation between visual and motor coordinate frames.

{922}
hide / / print
ref: Guenther-2009.12 tags: Guenther Kennedy 2009 neurotrophic electrode speech synthesize formant BMI date: 12-17-2011 02:12 gmt revision:2 [1] [0] [head]

PMID-20011034[0] A Wireless Brain-Machine Interface for Real-Time Speech Synthesis

  • Neurites grow into the glass electrode over the course of 3-4 months; the signals and neurons are henceforth stable, at least for the period prior publication (>4 years).
  • Used an FM modulator to send out the broadband neural signal; powered the implanted electronics inductively.
  • Sorted 56 spike clusters (!!)
    • quote: "We chose to err on the side of overestimating the number of clusters in our BMI since our Kalman filter decoding technique is somewhat robust to noisy inputs, whereas a stricter criterion for cluster definition might leave out information-carrying spike clusters."
    • 27 units on one wire and 29 on the other.
  • Quote: "neurons in the implanted region of left ventral premotor cortex represent intended speech sounds in terms of formant frequency trajectories, and projections from these neurons to primary motor cortex transform the intended formant trajectories into motor commands to the speech articulators."
    • Thus speech can be represented as a trajectory through formant space.
    • plus there are many simple low-load formant-based sw synthesizers
  • Used supervised methods (ridge regression), where the user was asked to imagine making vowel sounds mimicking what he heard.
    • only used the first 2 vowel formants; hence 2D task.
    • Supervised from 8 ~1-minute recording sessions.
  • 25 real-time feedback sessions over 5 months -- not much training time, why?
  • Video looks alright.

____References____

[0] Guenther FH, Brumberg JS, Wright EJ, Nieto-Castanon A, Tourville JA, Panko M, Law R, Siebert SA, Bartels JL, Andreasen DS, Ehirim P, Mao H, Kennedy PR, A wireless brain-machine interface for real-time speech synthesis.PLoS One 4:12, e8218 (2009 Dec 9)

{920}
hide / / print
ref: Arfin-2009.07 tags: ICMS birdsong wireless stimulation ARfin 2009 MIT date: 12-16-2011 04:21 gmt revision:1 [0] [head]

PMID-19386759[0] Wireless neural stimulation in freely behaving small animals.

  • Made a custom ASIC for delivering bipolar, biphasic current pulses.
  • 32 output channels.
  • Powered by small batteries
  • device in sleep state when not in use
  • controlled by inductive radio transfer with PWM modulation scheme.
  • Tested in Zebra finches, HVC: terminates song in all birds tested.
  • Impressive bit of engineering!

____References____

[0] Arfin SK, Long MA, Fee MS, Sarpeshkar R, Wireless neural stimulation in freely behaving small animals.J Neurophysiol 102:1, 598-605 (2009 Jul)

{921}
hide / / print
ref: Mavoori-2005.1 tags: Fetz ICMS stim wireless recording flash 2005 date: 12-16-2011 04:21 gmt revision:3 [2] [1] [0] [head]

PMID-16102841[0] An autonomous implantable computer for neural recording and stimulation in unrestrained primates.

  • Pretty basic: AFE + bandpass filter, 11.7ksps ADC, uC spike discriminator, microstimulator, IRDA link, 4Mbit flash (why so small? -- 2005).
  • Device could run for weeks at a time.
  • Used in his Hebbian learning task [1]

____References____

[0] Mavoori J, Jackson A, Diorio C, Fetz E, An autonomous implantable computer for neural recording and stimulation in unrestrained primates.J Neurosci Methods 148:1, 71-7 (2005 Oct 15)
[1] Jackson A, Mavoori J, Fetz EE, Long-term motor cortex plasticity induced by an electronic neural implant.Nature 444:7115, 56-60 (2006 Nov 2)

{156}
hide / / print
ref: Shidara-2002.05 tags: anterior cingulate ACC 2002 reward anticipation ODC date: 12-07-2011 04:12 gmt revision:1 [0] [head]

PMID-12040201[0] Anterior cingulate: single neuronal signals related to degree of reward expectancy

  • feelings of increasing anticipation experienced as we work toward a predicted outcome may be traceable to a reward expectancy signal; in OCD, the brain may be 'hijacked' by runaway signals in the reward expectancy circuit.
    • brain imaging studies have detected abnormal activation of ACC in OCD

____References____

[0] Shidara M, Richmond BJ, Anterior cingulate: single neuronal signals related to degree of reward expectancy.Science 296:5573, 1709-11 (2002 May 31)

{900}
hide / / print
ref: Helms-2003.01 tags: Schwartz BMI adaptive control Taylor Tillery 2003 date: 11-26-2011 00:58 gmt revision:1 [0] [head]

PMID-12929922 Training in cortical control of neuroprosthetic devices improves signal extraction from small neuronal ensembles.

  • Lays out the coadaprive algorithm.
  • with supervised / adaptive training, ML estimator is able to get 80% of the targets correct.
  • Reviews in the Neurosciences (conference) Workshop on Neural and Artificial Computation.

{780}
hide / / print
ref: -0 tags: chess evolution machine learning 2004 partial derivative date: 10-26-2009 04:07 gmt revision:2 [1] [0] [head]

A Self-learning Evolutionary Chess Program

  • The evolved program is able to perform at near master level!
  • Used object networks (neural networks that can be moved about according to the symmetries of the problem space). Paul Werbos apparently invented these, too.
  • Approached the problem by assigning values to having pieces at particular places on the board (PVT, positional value tables). The value of a move was the value of the resulting global valuation (sum of value of pieces - value of opponents pieces) + PVT. They used these valuations to look a set number of moves in the future, using an alpha-beta search.
    • Used 4-plys (search depth) while in normal genetic evolution; 6 when pawns would be upgraded.
  • The neural networks looked at the first 2 rows, the last two rows, and a 4x4 square in the middle of the board - areas known to matter in real games. (The main author is a master-level chess player and chess teacher).
  • The outputs of the three neural networks were added to the material and PVT values to assess a hypothetical board position.
  • Genetic selection operated on the PVT values, neural network weights, piece valuation, and biases of the neural networks. These were initialized semi-randomly; PVT values were initialized based on open-source programs.
  • Performed 50 generations of 20 players each. The top 10 players from each generation survived.
  • Gary Kasparov was consulted in this research. Cool!
  • I wonder what would happen if you allowed the program to propose (genetically or otherwise) alternate algorithmic structures. What they describe is purely a search through weight space - what about a genetic search through algorithmic structure space? Too difficult of a search?
  • I mean, that's what humans (the authors) do while they were designing this program/algorithm. The lead author, as mentioned, is already a very good chess player, and hence he could imbue the initial program with a lot of good 'filters' 'kernels' or 'glasses' for looking at the chess board. And how did he arrive at these ideas? Practice (raw data) and communication (other peoples kernels extracted from more raw data, and validated). And how does he play? By using his experience and knowledge to predict probable moves into the future, evaluating their value, and selecting the best. And how does he evaluate his algorithmic? The same way! By using his knowledge of both chess and computer science to simulate hypothetical designs in his head, seeing how he thinks they will perform, and selecting the best one.
  • The problem with present algorithms is that they have no sense of artistic beauty - no love of symmetry, whether it be simple geometric symmetry (beautiful people have symmetric faces) or more fractal (fractional-dimensioned) symmetry, e.g. music, fractals (duh), human art. I think symmetry can enormously cut down the dimension of the search space in learning, hence is frequently worthy of its own search.
    • Algorithms do presently have a good sense of parsimony, at least, through the AIC / regularization / SVD / bayes net's priors / etc. Parsimony can be beauty, too.
  • Another notable discrepancy is that humans can reason in a concrete way - they actively search for the thing that is causing the problem, the thing that is contributing greatly to either good or bad results. They do this by the scientific method, sorta - hold all other things constant, perturb some section of the system, measure the output. This is the same as taking a partial derivative. Such derivative are used heavily/exclusively in training neural networks - weights are changed based on the partial derivative of that weight wrt the output-referenced error. So reasoning is similar to non-parallel backprop? Or a really slow way of taking partial derivatives? Maybe. The goal of both is to assign valuation/causation to a given weight/subsystem.
  • Human reasoning involves dual valuation pathways - internal, based on a model of the world, and external, which of course involves experimentation and memory (and perhaps scholarly journal papers etc). The mammalian cortex-basal ganglia-thalamus loop seems designed for running these sorts of simulations because it is the dual of the problem of selecting appropriate behaviors. (there! I said it!) In internal simulation, you take world state, apply forward transform with perturbation, then evaluate the result - see if your perturbation (partial derivative) yields information. In motor behavior, you take the body state, apply forward transformation with perturbation (muscle contraction), and evaluate the result. Same thing. Of course you don't have to do this too much, as the cortex will remember the input-perturbation-result.
  • Understanding seems to be related to this input-transform-evaluate cycle, too, except here what is changing is the forward transform, and the output is compared to known output - does a given kernel (concept) predict the output/observed data?
  • Now what would happen if you applied this input-transform-evaluate to itself, e.g. you allowed the system to evaluate itself. Nothing? Recursion? (recursion is a very beautiful concept.) Some degree of awareness?
  • Surely someone has thought of this before, and tried to simulate it on a computer. Wasn't AI research all about this in the 70's-80's? People have said that their big problem was that AI was then entirely/mostly symbolic and insufficiently probabilistic or data-intensive; the 90's-21st century seems to have solved that. This field is unfamiliar to me, it'll take some sussing about before I can grok the academic landscape.
    • Even more surely, someone is doing it right now! This is the way the world advances. Same thing happened to me with GPGPU stuff, which I was doing in 2003. Now everyone is up to that shiznit.
  • It seems that machine-learning is transitioning from informing my personal philosophy, to becoming my philosophy. Good/bad? Feel free to edit this entry!
  • It's getting late and I'm tried -> rant ends.

{364}
hide / / print
ref: Linderman-2006.01 tags: neural recording technology compact flash stanford Shenoy 2006 date: 04-15-2009 20:55 gmt revision:3 [2] [1] [0] [head]

PMID-17946450[0] An Autonomous, broadband, multi-channel neural recording system for freely behaving primates

  • goal: recording system for freely-behaving animals.
    • problems: battery life, size
    • cannot sample broadband.
    • non autonomous.
  • solution:
    • compact flash, ARM core
    • accelerometer?
    • mounted inside the monkey's skull in the dental cement.
  • specs

____References____

[0] Linderman MD, Gilja V, Santhanam G, Afshar A, Ryu S, Meng TH, Shenoy KV, An autonomous, broadband, multi-channel neural recording system for freely behaving primates.Conf Proc IEEE Eng Med Biol Soc 1no Issue 1212-5 (2006)

{178}
hide / / print
ref: Churchland-2006.12 tags: motor_noise CNS Churchland execution variance motor_planning 2006 date: 12-08-2008 22:50 gmt revision:2 [1] [0] [head]

PMID-17178410[0] A central source of movement variability.

  • Small variations in preparatory neural activity were predictive of small variations in the upcoming reach
    • About half of the noise in reaching movements seems to be from variability during the preparatory phase, as estimated from regressions between preparatory neural activity and variability in performance.
  • even for a highly practiced task, the ability to repeatedly plan the same movement limits our ability to repeatedly execute the same movement.
  • when cocontraction increases, EMG variablility increases, but movement variability decreases. (This is consistent with poisson-based noise source?)
  • see the related articles!!

____References____

{649}
hide / / print
ref: notes-0 tags: ME270 project light power date: 12-08-2008 19:42 gmt revision:2 [1] [0] [head]

ME 270 Final Project - Optical Power Transfer

The purpose of this project was to develop a means for delivering optical power to the top of monkey unconstrained within his cage. This power will ultimately be used to recharge the batteries on a small neural telemetry device that we are developing. To deliver the power, we decided to use a moving-mirror DJ light controlled through a microcontroller in turn controlled via a video tracking computer. Hence, out report will be broken into three sections: the light, microcontroller, and video tracking.

{624} hide/ /

Section 1 : Reverse-engineering the light, part selection

Rather than engineering our own articulated spotlight, we elected to buy a moving-mirror DJ light; creating our own light source would simply have taken too much time, and demanded optical experience that we lack. After a brief survey, we bought an Elekralite mm150 (moving mirror, 150W bulb) DJ light, one of the cheapest on the market ($650); despite this, it is very well constructed, as you will see below. The light was originally controlled through the stage-specific DMX bus, but the possibility of directly controlling the light through this was discarded after we learned that the resolution on each axis is only 8 bits (+- 127); given the large range of the pan mirror, this is insufficient for tracking. Hence we decided to reverse engineer the light to determine the best way to directly control the mirror and shutter.
  • Overview, with dichroic color filter wheel and globos removed. We ended up putting these back in, as without them the unit does not initialize properly.
  • Another view with the shell taken off. The white ballast on the bottom powers the 150W HMI metal-halide bulb, along with a stabilization capacitor (to the left of the ballast) and starter (below the capacitor). The starter produces 2kV to initially ionize the gas in the bulb; there is no third starter electrode as in mercury vapor bulbs, as this would be a point of stress in the high-pressure (90atm) fused quartz arc tube. The bulb is on whenever the unit is plugged in, and the light output is controlled via the shutter. The top large transformer (+20V, +12V) is used to drive the display/control unit (left center) and the 6 stepper motors in the lamp, which are:
    • mirror tilt
    • mirror pan
    • shutter
    • globo selection
    • globo rotate
    • colorwheel
    • Detail of the breakout board for the 6 stepper motors, with the colorwheel stepper above it. The stepper motors are two-phase, permanent-magnet rotor types; we're not sure of the steps/revolution yet, though they all seem different. The breakout board also has attachments for the hall-effect sensors to detect orientation of the globo and color wheels.
    • The dichroic mirror color wheel. Regular filters would undoubtedly melt here - a pencil put into the beam of the HMI lamp will light on fire!
    • The globo wheel. Each globo is mounted to a gear which engages a center gear on the same axis as this plate. This center gear is driven by the globo rotate stepper motor.
    • Dichroic IR filter. Note that since it is viewed at an angle, the reflective wavelength goes up, and so you can see a slight red tint in the reflections off this. Removed this, since silicon photovoltaic cells respond to near IR energy.
    • Stepper motor controller. The three chips at the bottom are NXP 87LPC768 OTP microcontroller. Each can control two stepper motors, and each has an internal program for self-calibration using either the hall-effect sensors or hard mechanical limits on motor range. Upper chip is for the mirror (U3). These chips are controlled via one high-speed serial bus from the upper control board (the one with the LED display). The six upper chips, with heat-sinks on them, contain dual H-bridges, probably similar to the Allegro A3955 PWM microstepping motor driver. Between them are two standard 74HC04 hex inverters to drive the opposite leg of the h-bridges (each 87LPC768 has four outputs, two per motor, whereas each motor requires four inputs, two per phase. In this way, you can switch the direction of current flow through each motor phase with a single +20v supply rail.)
    • The Elekralite mm150 without the two control boards, globo wheel, or filter wheel. You can see the lamp, focus adjustment screws and reflector. Below the lamp is a 24V radial fan.
    • The Elektralite powered on, with globo and filter wheel back in place. The lamp is very, very bright!
    • Close-up of filter and globo wheels. The shutter has been removed; it fits on the shaft just above the long hex spacer. Just above that is the mechanical hard stop for the shutter.
    • The pin on the main controller that is used to control the 6 stepper axes. We tried probing it for some time, but could not directly figure out the serial protocol without a good logic analyzer (which is at home), so decided to implement our own microstepping PWM controller, and drive the inverters / H-bridges driectly.
    • The shutter, after being used for a good bit. The UV and IR from the lamp (mostly the IR, I think - the shutter gets really hot!) bleaches the black anodization on this bit of aluminum. We've drilled a 1/4" hole in one side to try to get a more tightly-collated beam.
    • The PWM waveform at the motor for the two phases (the glare at the left is from the light, which was of course on!). The other leads in the motor are simply the inverse of these via the 74HC04. For vector control like this, a 50% on/50% off PWM effectively sets the phase current to zero (the motor has sufficient leakage inductance at the 16kHz PWM frequency to keep di/dt low over multiple PWM periods). Hence, to control the motors we need something like:
      phase1 = 0.5*sin(theta) + 0.5 ; phase2 = 0.5*cos(theta) + 0.5
      , where theta is changed based on the control algorithm, and phase is scaled and used to set the PWM counter compare register. See below.
    • Microstepping control scheme based on vector control of current in the two phases of these stepper motors. As before, current will be regulated via PWM @ 16kHz, as the Elektralite engineers do, as opposed to linear current control. To generate the appropriate 6 PWM signals (mirror pan, mirror tilt, and shutter), we used a MSP430 microcontroller with 3 16-bit counters and 5+ capture-compare registers.
    • We used a MSP430F5xxx development board from TI -- see the next section. The device features sufficient timers and PWM outputs to control the stepper motors in the Elekralite. We will control motion of each using a simple up-down toggling via the parallel port to increment/decrement the motor theta variable. The microcontroller will need a look-up table or algorithm for calculating the sines and cosines of rotor angles.
    • small solar cell from Spark Fun Electronics. When placed in the beam of the light, it is possible to generate 500ma short-circuit current and 5V open-circuit voltage, but not at the same time. In a solar cell composed of a series of junctions, such as this, the total current at full voltage is limited by the minimum current from each of the junctions (they are in series!). Therefore to get maximum current you need very uniform illumination, something that is normally not difficult with the sun, but which will be difficult in this application. To avoid this problem we will try to procure higher efficiency single-junction GaAs concentrator cells, which can be up to ~40% efficient (as compared to this one, which is ~15% efficient).

Section 2: Microcontroller & microstepping

As mentioned before, we chose MSP430F5438 100-pin 16 bit microcontroller because it offers sufficient timers and speed for our problem and because we were both familiar with the architecture. Four 16-bit timers are used to control microstepping mirror tilt and pan, since the stepper motors have two phases. The microcontroller only needs to provide digital signals; current is provided through H-bridge drivers in the control board of the mm-150 - the DIPs with heat sinks below.

Opposite sides of the H-bridge are driven via hex inverters; hence, we only have to supply two PWM signals per motor, one per phase. Setting the PWM duty cycle to 50% will set the motor phase current to zero; by vectoring the duty cycle proportional to the sine and cosine of theta, where theta is the orientation of the motor * number of poles of the stepper, you can control microstepping. That, of course, is simplified; in practice, there are many details to contend with, namely:

  • The MSP430 is a 16 bit integer processor; hence, fractional values must be represented as fixed-point numbers. We chose 11-bit fixed point to optimize resolution and prevent overflow.
  • There is no divide. Division can be accomblished via bit-shifts (which is equivalent to dividing by 2), and addition.
  • There is one 16*16 -> 32 bit multiplier used as a peripheral in the MSP430 architecture, but the standard C library does not access it properly for our fixed-point math.
  • We have to approximate sine and cosine using fixed-point math, since the standard C library Sin and cos each take more than 2500 cycles -- too long when the microcontroller is only running at 12Mhz, and we want to update 4 microstepping phases at ~ 40Khz.

{646} hide/ /

We approximated sine and cosine, needed to vector the stepper motor phase currents, in fixed-point arithmetic first in C on linux - where the results could be plotted in matlab - before converting to MSP430 code. Since the trigonometric functions are repeating, we only need a polynomial approximation of sine from 0 to pi/2. The taylor series for sine is

 sin(x) = x - x^3/3! + x^5/5! - x^7/7! ...
; a quick check in matlab showed that the first three terms are enough to get an accurate approximation in the domain of interest. The MSP430 does not have division, however, so we approximated 1/3! = 1/6 as (1/8 + 1/32 + 1/128) and 1/5! = 1/120 as 1/128; division by powers of two is possible with right bit-shift operations. We chose base 11 (5 bits whole, 11 bits fractional) representation to avoid overflow: if 2^11 -> 1, we need to represent (pi/2)^5 -> 9.5 ; ceil(log_2(9.5)) = 4 (plus one bit for safety). The C program below shows this test.

#include <stdio.h>

char qsin(short i){
       //i goes from  0 pi/2 base 11 or...
       // 0 to 3217
       unsigned int cube, fifth, result;
       cube = (i*i) >> 11;
       cube = (cube*i) >> 11; //max = 7937
       fifth = (cube*i) >> 11;
       fifth = (fifth*i) >> 11; // max = 19585
       //our approximation to sine based on taylor series:
       //original: sin(x) = x - x^3/3! + x^5/5!
       //sin(x) = x - x^3*(1/8+1/32+1/128) + x^5*(1/128)
       result = (unsigned int)i -
               ((cube >> 3) + (cube >> 5) + (cube >> 7)) + (fifth >> 7);
       //result is base 11.  need it to be base 7.
       result = result >> 4;
       if(result > 127) result = 127;
       return (char)result;
}
//this is tricky, as it involves shifts, x-inversions, and y-inversions. 
//but it all makes sense if you plot out the respective functions. 
char isin(short i){
       // i is base 2^11
       //but we accept 0 to 2*pi or 12867
       if(i >= 0 && i < 3217) return qsin(i);
       else if(i >= 3217 && i < 6434) return qsin(6434 - i);
       else if(i >= 6434 && i < 9651) return -1*qsin(i - 6434);
       else if(i >= 9651 && i < 12867) return -1*qsin(12867 - i);
       else return 0;
}
char icos(short i){
       // i is base 2^11
       //but we accept 0 to 2*pi or 12867
       if(i >= 0 && i < 3217) return qsin(3217 - i);
       else if(i >= 3217 && i < 6434) return -1*qsin(i - 3217);
       else if(i >= 6434 && i < 9651) return -1*qsin(9651 - i);
       else if(i >= 9651 && i < 12867) return qsin(i - 9651);
       else return 0;
}

int main(void){
	short i; 
	for(i=0; i<12867; i++){
		printf("%d\t%f\t%d\t%d\n", i, ((float)i)/2048.0, (int)(isin(i)), (int)(icos(i))); 
	}
	return 0; 
}

We compiled and ran this program on the command line:

 gcc integer_trig.c 
 ./a.out > test.txt

Then we imported the data into matlab and plotted (Actual double floating-point sine and cosine are plotted on the same axis as thin black and magenta lines, respectively)

Later, we had to change the naive standard implementation of multiply to assembly to properly implement the fixed-point arithmetic - the MSP430's standard library did not implement the 16x16 multiply followed by shift correctly (it only keeps the bottom 16 bits). Note: this assembly function is for use with Code-Composer Studio, available from the Texas Instruments website. It seems that the IAR compiler uses different assembly syntax.

;*******************************************************************************
            .cdecls C,LIST,"msp430x54x.h"  ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Progam Start
;-------------------------------------------------------------------------------
                       
          ;;.sect "mply_11"
          ;;.asmfunc "mply_11"
                        .global mply_11 ;; this MUST BE PRECEDED BY TABS !!!!!

mply_11: 
        PUSH	SR	; 
         DINT		; turn off interrupts here. 
         NOP			; required after DINT
         MOV.W	R12, &MPY ; load the first operand. 
         MOV.W	R13, &OP2 ; load the second operand & start multiplication. 
         MOV.W	&RESLO, R12 ; low to R12 (this is the return value)
         MOV.W	&RESHI, R13 ; high to R13
         RRA.W R12 ; 1
         RRA.W R12 ; 2
         RRA.W R12 ; 3
         RRA.W R12 ; 4 
         RRA.W R12 ; 5
         RRA.W R12 ; 6
         RRA.W R12 ; 7
         RRA.W R12 ; 8
         RRA.W R12 ; 9
         RRA.W R12 ; 10
         RRA.W R12 ; 11
         
         RLA.W R13 ; 1
         RLA.W R13 ; 2
         RLA.W R13 ; 3
         RLA.W R13 ; 4
         RLA.W R13 ; 5
         
        ;; r14 can be clobbered across a function call, according to the msp430 ABI
        MOV.W	#0x001f, R14
        AND.W	R14, R12 ; mask off all but the bottom 5 bits from RESLO
         ADD.W	R13, R12 ; add (logical OR) the results. R12 is the 11-bit fixed point result.
         POP.W 	SR	;
         RETA		; return from subroutine.

            .end

Note the MSP430 does not have an opcode for multiple arithmetic shifts, nor does it have code for logical shifts - hence the need for repeated shifts and bitmasks!

Section 3 - Video tracking and host computer control

With the microcontroller done, we then moved to controlling it via a video-tracking computer. At this point, we had created a simple program for testing out parallel port control of the light's three axes using the keyboard (tilt, pan, and shutter). This program was split into two files, a main, and a set of subroutines that could then be called and compiled into the full video tracking program. It uses libparapin to abstract interaction with the parallel port in userspace.

First, the main loop, which is very simple:

#include "parallelout.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char g_main_loop ; 

int main(int argc, char *argv[])
{
	g_main_loop = 1; 
	char c;
	parallel_setup(); 
 
	while(1){
		c = fgetc(stdin);
		interpret_cmd(c); 
	}
}

Second, the parallel port controller. This uses a thread and circular queue to provide asynchronous, non-blocking control of the communications channel. Non-blocking is critical, as the program waits a small period between low-high transition of the interrupt pin (pin 4) for the MSP430 to read the status of the three lines.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <parapin.h>
#include <pthread.h>

#include "parallelout.h"

char g_q[1024]; //queue for the commands. 

int g_q_rptr; //where to read the next command from. 
int g_q_wptr; //where to put the next command

double g_velPan; 
double g_velTilt; 

void stepstep(void){
       int i = 0;
       for(i=0; i<20000; i++){
               set_pin(LP_PIN[4]);
               clear_pin(LP_PIN[4]);
	       set_pin(LP_PIN[5]);
               clear_pin(LP_PIN[5]);
	       set_pin(LP_PIN[5]);
               clear_pin(LP_PIN[5]);
       }
}

void velstep(int n){
	//printf("velstep %d\n", n); 
	clear_pin(LP_PIN[4]);
	if(n&0x1) set_pin(LP_PIN[2]) ; 
	else clear_pin(LP_PIN[2]); 
		
	if(n&0x2) set_pin(LP_PIN[3]) ; 
	else clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	//leave it up, so the msp430 knows it is a velocity command. 
}
void openShutter(){
	printf("opening shutter\n"); 
	clear_pin(LP_PIN[4]);
	set_pin(LP_PIN[2]); 
	set_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void closeShutter(){
	printf("closing shutter\n"); 
	clear_pin(LP_PIN[4]);
	clear_pin(LP_PIN[2]); 
	clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void smallShutter(){
	printf("small shutter\n"); 
	clear_pin(LP_PIN[4]);
	clear_pin(LP_PIN[2]); 
	set_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void stopMirror(){
	printf("stop mirror\n"); 
	clear_pin(LP_PIN[4]);
	set_pin(LP_PIN[2]); 
	clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}

void parallel_setup(){
	if (pin_init_user(LPT1) < 0)
		exit(0);

	pin_output_mode(LP_DATA_PINS | LP_SWITCHABLE_PINS);
	clear_pin(LP_PIN[2]);
	clear_pin(LP_PIN[3]); 
	clear_pin(LP_PIN[4]); 
	pthread_t thread1;
	//start the queue-servicing thread. 
	pthread_create ( &thread1, NULL, pq_thread, NULL ); 
}

void interpret_cmd(char cmd){
	//these codes don't make much sense unless you are 
	//controlling from a keyboard.
	switch(cmd){
		case 'w': velstep(0); g_velPan-=1.0; break; //pan to right (looking at but of light)
		case 'a': velstep(1); g_velTilt+=1.0; break; //tilt toward.
		case 's': velstep(2); g_velPan+=1.0; break; //pan to left
		case 'd': velstep(3); g_velTilt-=1.0; break; //tilt away
		case 'o': openShutter(); break; 
		case 'c': closeShutter(); break; 
		case 'x': smallShutter(); break;
		case ' ': stopMirror(); g_velPan=0; g_velTilt=0; break; 
	}
}

void usleep(int us){
	timespec ts; 
	ts.tv_sec = 0; 
	ts.tv_nsec = us * 1000; 
	nanosleep(&ts, NULL);
}

extern int g_main_loop ; 

void* pq_thread(void* a){
	while(g_main_loop){
		if(g_q_wptr > g_q_rptr){
			char cmd = g_q[g_q_rptr % sizeof(g_q)]; 
			g_q_rptr++; 
			interpret_cmd(cmd); 
		}
		usleep( 200 ); // run at max 500hz update.
		// the msp430 takes about 125us to service the parallel port irq.
	}
	return (void*)0;
}

void enqueue(char cmd){
	//this should be sufficiently atomic so there is no thread contention.
	g_q[g_q_wptr % sizeof(g_q)] = cmd; 
	g_q_wptr++; 
}

Then, we worked on the video tracking program. I will omit the some of the noncritical sections involving the firewire (ieee1394), Xv (video display) and X11 (window manager) calls, as the whole program is long, ~1000 lines. Below is 'main' -- see the comments for a detailed description.

int main(int arc, char *argv[]){
	int i; 
	double t1, t2, t3, t4; 
	t1 = t2 = t3 = t4 = 0.0; 
	signal(SIGINT, cleanup); //trap cntrl c
	signal(SIGPIPE, cleanup);
	//turn off output buffering for ttcp!
	//setvbuf(stdout,(char*)NULL,_IONBF,0);
	//init buffers for old tracking... 
	for(int i=0; i<4; i++){
                g_buffer[i] = (short*)malloc(640*480*sizeof(short)); 
        }
        g_averagefb = (int*)malloc(640*480*sizeof(int)); 
        g_velfb = (int*)malloc(640*480*sizeof(int));
        g_lastfb = (unsigned char*)malloc(640*480);	
        g_trackedfb = (unsigned char*)malloc(640*480);	
        for(i=0; i < 640*480; i++){
                g_averagefb[i] = 0; 
        }
	//Step -2: set up threads (the display runs on a seperate thread
	// to keep from blocking the iscochronous recieve channel
	// and hence causing the frame rate to drop. 
	pthread_mutex_init(&g_dispthread_mutex, NULL); 
	pthread_cond_init(&g_dispthread_cond, NULL); 
	//STEP -1: init the parallel port for control of mirror (this also starts that thread)
	parallel_setup(); 
	//Step 0: small shutter so we can track the light easily. 
	smallShutter(); 
	//Step 0.5: move the mirror to the close left (from but of light) for calibration
	//for reference (from the viewpoint of the cord end of the light): 
	// pan left : s
	// pan right: w
	// tilt toward: a
	// tilt away: s
	// small shutter: x
	// open shutter: o
	// closed shutter: c
	// stop mirrors : <space>
	for(i=0; i<10; i++){
		enqueue('s'); //to the left if you are looking at the but of the light.
		enqueue('a'); //the tilt axis has far fewer steps for full range than
		enqueue('s'); // the pan axis hence requires a much higher velocity - 
		enqueue('s'); // so enqueue more 's'. 
		enqueue('s'); 
		enqueue('s'); 
	}
	//Step 1: Open ohci and assign a handle to it.
	//==================================================================================================================
	init_cards();
        //Step 2: Get the camera nodes and describe them as we find them.
	//==================================================================================================================
	init_cams();
        //Step 3: Setup Capture
	//==================================================================================================================
	setup_cams();
	//Step 4: Start sending data
	//==================================================================================================================
	start_iso_transmission();
	//start the other thread. 
	pthread_t thread1;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_create( &thread1, &attr, display_thread, 0 ); 
	
	//Main event loop
	while(g_main_loop==true){
		for( i=0; i<numCameras; i++){
			if(dc1394_dma_single_capture(&camera[i]) != DC1394_SUCCESS){
				fprintf(stderr, "dma1394: Failed to capture from cameras\n");
				cleanup(0);
			}
		}
		t2=get_time();
		for( i=0; i<numCameras; i++){
			//display_frames_old(i);
			display_frames(i);
			/*if((g_frame%60) < 15){
				velstep(0); 
			}else if((g_frame%60) < 45){
				velstep(2); 
			}else {
				velstep(0); 
			}	*/			
			if(dc1394_dma_done_with_buffer(&camera[i]) != DC1394_SUCCESS){
				fprintf(stderr, "dma1394: Can't release dma bufer\n");
			}
		}
		
		if(g_frame % 60 == 0){
			printf("frame dt: %f (%f) track time %f (%f)\n", t2-t4, 1/(t2-t4), tracktime, 1/(tracktime)); 
		}
		//start with the state machine for the calibration -- 
		if(g_frame == CALIB_0){
			enqueue(' '); //stop it
			printf("!!assuming that the mirror reached it's limit!!\n");
			for( i=0; i<3; i++){
				//now that we have put the mirror into a corner, give it velocity
				// to move to the center of the FOV so that we may turn on 
				// feedback-based tracking. 
				enqueue('w'); //to the left if you are looking at the but of the light.
				enqueue('d'); 
				enqueue('w'); //again, pan motor has many more steps/range than tilt
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
			}
		}
		if(g_frame == CALIB_1){
			enqueue(' '); //stop it
			printf("!!assuming light is centered now!!\n");
		}
		if(g_frame == CALIB_2){
			enqueue('x');  
		}
		t4 = t2; 
		g_frame++; 
	}
	cleanup(0); 
	return 0;
}

Our tracking algorithm periodically opens and closes the shutter on the light. It is impossible to track a target based on brightness or even pattern detection, since the light is so bright it is impossible to image what it hits and what it does not with our cameras of limited dynamic range. (The human eye, of course, has far better dynamic range.) During the period when the light is off, we wait for the camera shutter speed to stabilize, then average the brightest spot over 10 consecutive frames to obtain a target position. Then, the shutter is opened, and visual feedback is used with a simple PD controller to guide the light to the target. When the device is deployed, we will make the update non-periodic and purely contingent on the detection of motion or of decreased solar cell output. See below for the thread that implements this logic, as well as blits the image onto the screen.

void* display_thread(void* ptr ){
	make_window(); 
	while(g_main_loop){
		if(pthread_cond_wait(&g_dispthread_cond, &g_dispthread_mutex) == 0){
			pthread_mutex_unlock(&g_dispthread_mutex); 
			double t1 = get_time(); 
			g_first_frame=false;
			//convert into the XV format (this seems very inefficient to me...)
			for(unsigned int i=0; i< g_framewidth*g_frameheight; i++){
				g_fb[i] = g_trackedfb[i]+ 0x8000;
			}
			double c_r, c_c; 
			new_track(0, &tcam[0], g_trackedfb, 
				g_framewidth, g_frameheight, CONTRAST_MIN, SEARCHR, 
				GAUSSDROPOFF, NUMBER_OF_MARKERS, &c_r, &c_c);
			xv_image=XvCreateImage(display, info[adaptor].base_id, 
				format_disp, (char*)g_fb, g_framewidth, g_frameheight*numCameras);
			XvPutImage(display, info[adaptor].base_id, window, gc, xv_image, 0, 
				0, g_framewidth, g_frameheight*numCameras, 0, 0,
				g_windowwidth, g_windowheight);
			free(xv_image); 
			
			//do some dumb control (finally!)
			// initially, guide the light to the center of the screen. 
			if(g_frame > CALIB_1 && g_frame <= CALIB_2){
				g_target_c = 320.0; 
				g_target_r = 240.0; 
				servo_mirror(c_c, c_r); //get it stuck on the center! 
			}
			int time = g_frame - CALIB_2; 
			// below is the *main loop* for cycling the shutter open/close
			if(g_frame > CALIB_2){
				if(time % 300 < 240){
					servo_mirror(c_c, c_r); 
				}
				if(time % 300 == 240){
					enqueue('c'); 
					enqueue(' '); 
				}
				if(time % 300  >= 260 && time % 300  < 280 ){
					g_target_c += c_c; 
					g_target_r += c_r; 
				}
				if(time % 300 == 280){
					enqueue('x'); 
					g_target_c /= 20.0; 
					g_target_r /= 20.0; 
				}
			}
			double t2 = get_time(); 
			tracktime = t2 - t1 ; 
		}
		//normalize_com(NUMBER_OF_MARKERS);
		XFlush(display);
		while(XPending(display)>0){
			XNextEvent(display,&xev);
			switch(xev.type){
				case ConfigureNotify:
					g_windowwidth=xev.xconfigure.width;
					g_windowheight=xev.xconfigure.height;
				break;
				case KeyPress:
					switch(XKeycodeToKeysym(display,xev.xkey.keycode,0)){
						case XK_q:
						case XK_Q:
							g_main_loop = false; 
							//cleanup(0);
						break;
						}
				break;
			}
		} //XPending
	}
	if ((void *)window != NULL){
		XUnmapWindow(display,window);
	}
	fprintf(stderr,"dma1394: Unmapped Window.\n");
	if (display != NULL){
		XFlush(display);
	}
	return (void*) 0;
}

The PD controller uses very pessimistic values for the coefficients, as we discovered that the timing resolution on out older linux computer is low - about 5ms. This means that if too many velocity step commands are sent to the parallel port thread at one time, it will get backlogged, which will induce a phase-shift between control and actuation of velocity. Hence, the light must move rather slowly, on the order of one velocity step on each axis per frame. Again, below.

void servo_mirror(double c_c, double c_r ){
	double dc = c_c - g_target_c; //for now assume that we want to stabilize in
	double dr = c_r - g_target_r; // the center.
	double vgain = 8.0 ; 
	double pgain = 1.0/80.0; 
	int lim = 1; 
	double c = dc + g_velPan*vgain ; 
	int ccmd = 0; 
	int rcmd = 0; 
	if(c > 0){
		for(int i=0; i<c*pgain && i < lim; i++){
			enqueue('w');
			ccmd --; 
		}
	}
	if(c < 0){
		for(int i=0; i<c*-1.0*pgain && i < lim; i++){
			enqueue('s');
			ccmd ++; 
		}
	}
		
	vgain *= 1.5; //tilt mirror moves quicker!
	double r = dr + g_velTilt*vgain;
	if(r>0){
		for(int i=0; i<r*pgain && i < lim; i++){
			enqueue('d');
			rcmd--; 
		}
	}
	if(r<0){
		for(int i=0; i<r*-1.0*pgain && i < lim; i++){
			enqueue('a');
			rcmd++; 
		}
	}
	//this for debugging loop stability problems in matlab. 
	//printf("%f %f %d %f %f %d\n", dc, g_velPan*vgain, ccmd, dr, g_velTilt*vgain, rcmd); 
	//if(dr + g_velTilt*vgain > 0) enqueue('d'); OLD
	//if(dr + g_velTilt*vgain < 0) enqueue('a'); 
}

Our video tracking algorithm first uses a tree-like algorithm to quickly and robustly search for the brightest region in the scene; we presume, somewhat simplistically, that this will be the target. When the device is put into use with an actual monkey cage, we'll surround the camera with high-intensity infrared LEDs to effectively illuminate a retroreflector placed on the monkey's head. Below is the code which performs this computation.

//make a blur matrix
//void blur(frame_info* frame, unsigned char * fb, int framewidth, int downsamp, int downsamp_w, int downsamp_h){
void blur(int camno, track_cam* tcam, unsigned char* fb, int framewidth, int downsamp_r, int downsamp_c, int downsamp_w, int downsamp_h){
	//initialize contrasts
	for(int m=0; m<downsamp_r * downsamp_c; m++){
		tcam[camno].frame.sum[m]=0;
		tcam[camno].frame.contr_min[m]=255;
		tcam[camno].frame.contr_max[m]=0;
	}
	for(int k=0; k<downsamp_r; k++){	
		for(int row=k*downsamp_h; row<k*downsamp_h+downsamp_h; row++){
			for(int j=0; j<downsamp_c; j++){
				for(int col=j*downsamp_w; col<j*downsamp_w+downsamp_w; col++){
					tcam[camno].frame.sum[j+(k*downsamp_c)]+=int(fb[row*framewidth+col]);
					if(int(fb[row*framewidth+col])>tcam[camno].frame.contr_max[j+(k*downsamp_c)]){
						tcam[camno].frame.contr_max[j+(k*downsamp_c)]=int(fb[row*framewidth+col]); //introducing a contrast check.  
					}
					if(int(fb[row*framewidth+col])<tcam[camno].frame.contr_min[j+(k*downsamp_c)]){
						tcam[camno].frame.contr_min[j+(k*downsamp_c)]=int(fb[row*framewidth+col]); //introducing a contrast check
					}
				}
			}
		}
	}
}

//blob_search function
//search through the sum matrix and find the brightest sums
//void blob_search(frame_info* frame, marker* marker, int num_markers, int contrast_min){
void blob_search(int camno, track_cam* tcam, int num_markers, int contrast_min, int downsamp_r, int downsamp_c){
	//frame->num_blobs=0; //innocent until proven guilty
	for(int i=0; i<num_markers; i++){
		int blob_val=0;
		for(int m=0; m<downsamp_r*downsamp_c; m++){
			if(tcam[camno].frame.sum[m]>blob_val && tcam[camno].frame.contr_max[m]-tcam[camno].frame.contr_min[m]>contrast_min){ //has to have a big contrast to be a blob (CONTRAST is user defined macro)
				blob_val=tcam[camno].frame.sum[m]; //the new max'
				tcam[camno].marker[i].downsamp_loc=m; //the sum integer (0-255)
				//frame->num_blobs++;
			}
		}
		tcam[camno].frame.sum[tcam[camno].marker[i].downsamp_loc]=0; //kill the one we just found so we can find the next biggest one.
	}
}

//brightest_pix_search function
//search through the blobs for the brightest pixel
//void brightest_pix_search(unsigned char * fb, frame_info* frame, marker* marker, int num_markers, int framewidth, int downsamp, int downsamp_w, int downsamp_h){
void brightest_pix_search(unsigned char * fb, int camno, track_cam* tcam, int num_markers, int framewidth, int downsamp_r, int downsamp_c, int downsamp_w, int downsamp_h){
	//br_pix_info[0] is the row
	//br_pix_info[1] is the col
	//br_pix_info[2] is the value
	for(int i=0; i<num_markers; i++){
		tcam[camno].marker[i].br_pix_val=0; //always has to start low
		for(int row=int(floor(tcam[camno].marker[i].downsamp_loc/downsamp_c))*downsamp_h; row<int(floor(tcam[camno].marker[i].downsamp_loc/downsamp_c))*downsamp_h+downsamp_h; row++){
			for(int col=tcam[camno].marker[i].downsamp_loc%downsamp_c*downsamp_w; col<tcam[camno].marker[i].downsamp_loc%downsamp_c*downsamp_w+downsamp_w; col++){
				if(int(fb[row*framewidth+col])>tcam[camno].marker[i].br_pix_val){ //if it is greater than the brightest pixel then store its info
					tcam[camno].marker[i].br_pix_row=row; //save the row
					tcam[camno].marker[i].br_pix_col=col; //save the column
					tcam[camno].marker[i].br_pix_val=int(fb[row*framewidth+col]); //save the value
				}
			}
		}
	}
}

The blocking (or blobbing) and search algorithm yields the estimated location of the brightest pixel in the image. This is passed to a specialized array-growth region growing algorithm which dynamically expands a region around the suggested brightest pixel to include all pixels that are within a threshold of brightness to the brightest. The region growing algorithm then computes the center of mass from the list of pixel coordinates, which are then passed to the PD and target location routines.

void region_grow(unsigned char * src, unsigned short* dest, 
		int w, int h, int b_r, int b_c, double* c_r, double* c_c){
	//need to do an expansion from the brightest point. 
	//this is sorta a random-access op - which is bad. 
	unsigned short fill = 0xff00; 
	int n = 0; 
	short r, c; 
	int  i, p; 
	unsigned char thresh = 20 ; 
	unsigned char brightest = src[w*b_r + b_c]; 
	g_rows[n] = b_r; 
	g_cols[n] = b_c; 
	n++; 
	int sta = 0; 
	int end = 0; 
	int lim = sizeof(g_rows)/sizeof(int); 
	while(n < lim && n > sta){
		//loop through all the new points, adding to the set as we go. 
		end = n; 
		for(i=sta; i < end; i++){
			r = g_rows[i]; 
			c =  g_cols[i]; 
			r++; //down
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			r -= 2; //up.
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			r++; //center
			c++; //to the right. 
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			c-=2; //to the left. 
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
		}//end loop over past points. 
		sta = end; 
	}
	//calculate the center of mass. 
	double cm_r = 0; 
	double cm_c = 0; 
	for(i=0; i<n; i++){
		cm_r += g_rows[i]; 
		cm_c += g_cols[i]; 
	}
	cm_r /= n; 
	cm_c /= n; 
	*c_r = cm_r; 
	*c_c = cm_c; 
	//printf("point: %f %f %d \n",  cm_r, cm_c, g_frame++); 
	int cm_r_i, cm_c_i; 
	cm_r_i = (int)cm_r; 
	cm_c_i = (int)cm_c; 
	if(cm_c_i >= 0 && cm_c_i < w && cm_r_i >= 0 && cm_r_i < h)
		dest[cm_r_i*w + cm_c_i] = 0xffff; 
}

And that is, roughly, the entirety of the video tracking program! (Most of the rest of the code deals with the firewire bus and other less interesting details.) We conclude with a picture of the whole setup in the office.

{648}
hide / / print
ref: notes-0 tags: ME270 light video tracking date: 12-04-2008 00:07 gmt revision:0 [head]

Section 3 - Video tracking and host computer control

With the microcontroller done, we then moved to controlling it via a video-tracking computer. At this point, we had created a simple program for testing out parallel port control of the light's three axes using the keyboard (tilt, pan, and shutter). This program was split into two files, a main, and a set of subroutines that could then be called and compiled into the full video tracking program. It uses libparapin to abstract interaction with the parallel port in userspace.

First, the main loop, which is very simple:

#include "parallelout.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char g_main_loop ; 

int main(int argc, char *argv[])
{
	g_main_loop = 1; 
	char c;
	parallel_setup(); 
 
	while(1){
		c = fgetc(stdin);
		interpret_cmd(c); 
	}
}

Second, the parallel port controller. This uses a thread and circular queue to provide asynchronous, non-blocking control of the communications channel. Non-blocking is critical, as the program waits a small period between low-high transition of the interrupt pin (pin 4) for the MSP430 to read the status of the three lines.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <parapin.h>
#include <pthread.h>

#include "parallelout.h"

char g_q[1024]; //queue for the commands. 

int g_q_rptr; //where to read the next command from. 
int g_q_wptr; //where to put the next command

double g_velPan; 
double g_velTilt; 

void stepstep(void){
       int i = 0;
       for(i=0; i<20000; i++){
               set_pin(LP_PIN[4]);
               clear_pin(LP_PIN[4]);
	       set_pin(LP_PIN[5]);
               clear_pin(LP_PIN[5]);
	       set_pin(LP_PIN[5]);
               clear_pin(LP_PIN[5]);
       }
}

void velstep(int n){
	//printf("velstep %d\n", n); 
	clear_pin(LP_PIN[4]);
	if(n&0x1) set_pin(LP_PIN[2]) ; 
	else clear_pin(LP_PIN[2]); 
		
	if(n&0x2) set_pin(LP_PIN[3]) ; 
	else clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	//leave it up, so the msp430 knows it is a velocity command. 
}
void openShutter(){
	printf("opening shutter\n"); 
	clear_pin(LP_PIN[4]);
	set_pin(LP_PIN[2]); 
	set_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void closeShutter(){
	printf("closing shutter\n"); 
	clear_pin(LP_PIN[4]);
	clear_pin(LP_PIN[2]); 
	clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void smallShutter(){
	printf("small shutter\n"); 
	clear_pin(LP_PIN[4]);
	clear_pin(LP_PIN[2]); 
	set_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}
void stopMirror(){
	printf("stop mirror\n"); 
	clear_pin(LP_PIN[4]);
	set_pin(LP_PIN[2]); 
	clear_pin(LP_PIN[3]); 
	set_pin(LP_PIN[4]); 
	clear_pin(LP_PIN[4]); //clear the trigger to indicate a shutter command. 
}

void parallel_setup(){
	if (pin_init_user(LPT1) < 0)
		exit(0);

	pin_output_mode(LP_DATA_PINS | LP_SWITCHABLE_PINS);
	clear_pin(LP_PIN[2]);
	clear_pin(LP_PIN[3]); 
	clear_pin(LP_PIN[4]); 
	pthread_t thread1;
	//start the queue-servicing thread. 
	pthread_create ( &thread1, NULL, pq_thread, NULL ); 
}

void interpret_cmd(char cmd){
	//these codes don't make much sense unless you are 
	//controlling from a keyboard.
	switch(cmd){
		case 'w': velstep(0); g_velPan-=1.0; break; //pan to right (looking at but of light)
		case 'a': velstep(1); g_velTilt+=1.0; break; //tilt toward.
		case 's': velstep(2); g_velPan+=1.0; break; //pan to left
		case 'd': velstep(3); g_velTilt-=1.0; break; //tilt away
		case 'o': openShutter(); break; 
		case 'c': closeShutter(); break; 
		case 'x': smallShutter(); break;
		case ' ': stopMirror(); g_velPan=0; g_velTilt=0; break; 
	}
}

void usleep(int us){
	timespec ts; 
	ts.tv_sec = 0; 
	ts.tv_nsec = us * 1000; 
	nanosleep(&ts, NULL);
}

extern int g_main_loop ; 

void* pq_thread(void* a){
	while(g_main_loop){
		if(g_q_wptr > g_q_rptr){
			char cmd = g_q[g_q_rptr % sizeof(g_q)]; 
			g_q_rptr++; 
			interpret_cmd(cmd); 
		}
		usleep( 200 ); // run at max 500hz update.
		// the msp430 takes about 125us to service the parallel port irq.
	}
	return (void*)0;
}

void enqueue(char cmd){
	//this should be sufficiently atomic so there is no thread contention.
	g_q[g_q_wptr % sizeof(g_q)] = cmd; 
	g_q_wptr++; 
}

Then, we worked on the video tracking program. I will omit the some of the noncritical sections involving the firewire (ieee1394), Xv (video display) and X11 (window manager) calls, as the whole program is long, ~1000 lines. Below is 'main' -- see the comments for a detailed description.

int main(int arc, char *argv[]){
	int i; 
	double t1, t2, t3, t4; 
	t1 = t2 = t3 = t4 = 0.0; 
	signal(SIGINT, cleanup); //trap cntrl c
	signal(SIGPIPE, cleanup);
	//turn off output buffering for ttcp!
	//setvbuf(stdout,(char*)NULL,_IONBF,0);
	//init buffers for old tracking... 
	for(int i=0; i<4; i++){
                g_buffer[i] = (short*)malloc(640*480*sizeof(short)); 
        }
        g_averagefb = (int*)malloc(640*480*sizeof(int)); 
        g_velfb = (int*)malloc(640*480*sizeof(int));
        g_lastfb = (unsigned char*)malloc(640*480);	
        g_trackedfb = (unsigned char*)malloc(640*480);	
        for(i=0; i < 640*480; i++){
                g_averagefb[i] = 0; 
        }
	//Step -2: set up threads (the display runs on a seperate thread
	// to keep from blocking the iscochronous recieve channel
	// and hence causing the frame rate to drop. 
	pthread_mutex_init(&g_dispthread_mutex, NULL); 
	pthread_cond_init(&g_dispthread_cond, NULL); 
	//STEP -1: init the parallel port for control of mirror (this also starts that thread)
	parallel_setup(); 
	//Step 0: small shutter so we can track the light easily. 
	smallShutter(); 
	//Step 0.5: move the mirror to the close left (from but of light) for calibration
	//for reference (from the viewpoint of the cord end of the light): 
	// pan left : s
	// pan right: w
	// tilt toward: a
	// tilt away: s
	// small shutter: x
	// open shutter: o
	// closed shutter: c
	// stop mirrors : <space>
	for(i=0; i<10; i++){
		enqueue('s'); //to the left if you are looking at the but of the light.
		enqueue('a'); //the tilt axis has far fewer steps for full range than
		enqueue('s'); // the pan axis hence requires a much higher velocity - 
		enqueue('s'); // so enqueue more 's'. 
		enqueue('s'); 
		enqueue('s'); 
	}
	//Step 1: Open ohci and assign a handle to it.
	//==================================================================================================================
	init_cards();
        //Step 2: Get the camera nodes and describe them as we find them.
	//==================================================================================================================
	init_cams();
        //Step 3: Setup Capture
	//==================================================================================================================
	setup_cams();
	//Step 4: Start sending data
	//==================================================================================================================
	start_iso_transmission();
	//start the other thread. 
	pthread_t thread1;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_create( &thread1, &attr, display_thread, 0 ); 
	
	//Main event loop
	while(g_main_loop==true){
		for( i=0; i<numCameras; i++){
			if(dc1394_dma_single_capture(&camera[i]) != DC1394_SUCCESS){
				fprintf(stderr, "dma1394: Failed to capture from cameras\n");
				cleanup(0);
			}
		}
		t2=get_time();
		for( i=0; i<numCameras; i++){
			//display_frames_old(i);
			display_frames(i);
			/*if((g_frame%60) < 15){
				velstep(0); 
			}else if((g_frame%60) < 45){
				velstep(2); 
			}else {
				velstep(0); 
			}	*/			
			if(dc1394_dma_done_with_buffer(&camera[i]) != DC1394_SUCCESS){
				fprintf(stderr, "dma1394: Can't release dma bufer\n");
			}
		}
		
		if(g_frame % 60 == 0){
			printf("frame dt: %f (%f) track time %f (%f)\n", t2-t4, 1/(t2-t4), tracktime, 1/(tracktime)); 
		}
		//start with the state machine for the calibration -- 
		if(g_frame == CALIB_0){
			enqueue(' '); //stop it
			printf("!!assuming that the mirror reached it's limit!!\n");
			for( i=0; i<3; i++){
				//now that we have put the mirror into a corner, give it velocity
				// to move to the center of the FOV so that we may turn on 
				// feedback-based tracking. 
				enqueue('w'); //to the left if you are looking at the but of the light.
				enqueue('d'); 
				enqueue('w'); //again, pan motor has many more steps/range than tilt
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
				enqueue('w');
			}
		}
		if(g_frame == CALIB_1){
			enqueue(' '); //stop it
			printf("!!assuming light is centered now!!\n");
		}
		if(g_frame == CALIB_2){
			enqueue('x');  
		}
		t4 = t2; 
		g_frame++; 
	}
	cleanup(0); 
	return 0;
}

Our tracking algorithm periodically opens and closes the shutter on the light. It is impossible to track a target based on brightness or even pattern detection, since the light is so bright it is impossible to image what it hits and what it does not with our cameras of limited dynamic range. (The human eye, of course, has far better dynamic range.) During the period when the light is off, we wait for the camera shutter speed to stabilize, then average the brightest spot over 10 consecutive frames to obtain a target position. Then, the shutter is opened, and visual feedback is used with a simple PD controller to guide the light to the target. When the device is deployed, we will make the update non-periodic and purely contingent on the detection of motion or of decreased solar cell output. See below for the thread that implements this logic, as well as blits the image onto the screen.

void* display_thread(void* ptr ){
	make_window(); 
	while(g_main_loop){
		if(pthread_cond_wait(&g_dispthread_cond, &g_dispthread_mutex) == 0){
			pthread_mutex_unlock(&g_dispthread_mutex); 
			double t1 = get_time(); 
			g_first_frame=false;
			//convert into the XV format (this seems very inefficient to me...)
			for(unsigned int i=0; i< g_framewidth*g_frameheight; i++){
				g_fb[i] = g_trackedfb[i]+ 0x8000;
			}
			double c_r, c_c; 
			new_track(0, &tcam[0], g_trackedfb, 
				g_framewidth, g_frameheight, CONTRAST_MIN, SEARCHR, 
				GAUSSDROPOFF, NUMBER_OF_MARKERS, &c_r, &c_c);
			xv_image=XvCreateImage(display, info[adaptor].base_id, 
				format_disp, (char*)g_fb, g_framewidth, g_frameheight*numCameras);
			XvPutImage(display, info[adaptor].base_id, window, gc, xv_image, 0, 
				0, g_framewidth, g_frameheight*numCameras, 0, 0,
				g_windowwidth, g_windowheight);
			free(xv_image); 
			
			//do some dumb control (finally!)
			// initially, guide the light to the center of the screen. 
			if(g_frame > CALIB_1 && g_frame <= CALIB_2){
				g_target_c = 320.0; 
				g_target_r = 240.0; 
				servo_mirror(c_c, c_r); //get it stuck on the center! 
			}
			int time = g_frame - CALIB_2; 
			// below is the *main loop* for cycling the shutter open/close
			if(g_frame > CALIB_2){
				if(time % 300 < 240){
					servo_mirror(c_c, c_r); 
				}
				if(time % 300 == 240){
					enqueue('c'); 
					enqueue(' '); 
				}
				if(time % 300  >= 260 && time % 300  < 280 ){
					g_target_c += c_c; 
					g_target_r += c_r; 
				}
				if(time % 300 == 280){
					enqueue('x'); 
					g_target_c /= 20.0; 
					g_target_r /= 20.0; 
				}
			}
			double t2 = get_time(); 
			tracktime = t2 - t1 ; 
		}
		//normalize_com(NUMBER_OF_MARKERS);
		XFlush(display);
		while(XPending(display)>0){
			XNextEvent(display,&xev);
			switch(xev.type){
				case ConfigureNotify:
					g_windowwidth=xev.xconfigure.width;
					g_windowheight=xev.xconfigure.height;
				break;
				case KeyPress:
					switch(XKeycodeToKeysym(display,xev.xkey.keycode,0)){
						case XK_q:
						case XK_Q:
							g_main_loop = false; 
							//cleanup(0);
						break;
						}
				break;
			}
		} //XPending
	}
	if ((void *)window != NULL){
		XUnmapWindow(display,window);
	}
	fprintf(stderr,"dma1394: Unmapped Window.\n");
	if (display != NULL){
		XFlush(display);
	}
	return (void*) 0;
}

The PD controller uses very pessimistic values for the coefficients, as we discovered that the timing resolution on out older linux computer is low - about 5ms. This means that if too many velocity step commands are sent to the parallel port thread at one time, it will get backlogged, which will induce a phase-shift between control and actuation of velocity. Hence, the light must move rather slowly, on the order of one velocity step on each axis per frame. Again, below.

void servo_mirror(double c_c, double c_r ){
	double dc = c_c - g_target_c; //for now assume that we want to stabilize in
	double dr = c_r - g_target_r; // the center.
	double vgain = 8.0 ; 
	double pgain = 1.0/80.0; 
	int lim = 1; 
	double c = dc + g_velPan*vgain ; 
	int ccmd = 0; 
	int rcmd = 0; 
	if(c > 0){
		for(int i=0; i<c*pgain && i < lim; i++){
			enqueue('w');
			ccmd --; 
		}
	}
	if(c < 0){
		for(int i=0; i<c*-1.0*pgain && i < lim; i++){
			enqueue('s');
			ccmd ++; 
		}
	}
		
	vgain *= 1.5; //tilt mirror moves quicker!
	double r = dr + g_velTilt*vgain;
	if(r>0){
		for(int i=0; i<r*pgain && i < lim; i++){
			enqueue('d');
			rcmd--; 
		}
	}
	if(r<0){
		for(int i=0; i<r*-1.0*pgain && i < lim; i++){
			enqueue('a');
			rcmd++; 
		}
	}
	//this for debugging loop stability problems in matlab. 
	//printf("%f %f %d %f %f %d\n", dc, g_velPan*vgain, ccmd, dr, g_velTilt*vgain, rcmd); 
	//if(dr + g_velTilt*vgain > 0) enqueue('d'); OLD
	//if(dr + g_velTilt*vgain < 0) enqueue('a'); 
}

Our video tracking algorithm first uses a tree-like algorithm to quickly and robustly search for the brightest region in the scene; we presume, somewhat simplistically, that this will be the target. When the device is put into use with an actual monkey cage, we'll surround the camera with high-intensity infrared LEDs to effectively illuminate a retroreflector placed on the monkey's head. Below is the code which performs this computation.

//make a blur matrix
//void blur(frame_info* frame, unsigned char * fb, int framewidth, int downsamp, int downsamp_w, int downsamp_h){
void blur(int camno, track_cam* tcam, unsigned char* fb, int framewidth, int downsamp_r, int downsamp_c, int downsamp_w, int downsamp_h){
	//initialize contrasts
	for(int m=0; m<downsamp_r * downsamp_c; m++){
		tcam[camno].frame.sum[m]=0;
		tcam[camno].frame.contr_min[m]=255;
		tcam[camno].frame.contr_max[m]=0;
	}
	for(int k=0; k<downsamp_r; k++){	
		for(int row=k*downsamp_h; row<k*downsamp_h+downsamp_h; row++){
			for(int j=0; j<downsamp_c; j++){
				for(int col=j*downsamp_w; col<j*downsamp_w+downsamp_w; col++){
					tcam[camno].frame.sum[j+(k*downsamp_c)]+=int(fb[row*framewidth+col]);
					if(int(fb[row*framewidth+col])>tcam[camno].frame.contr_max[j+(k*downsamp_c)]){
						tcam[camno].frame.contr_max[j+(k*downsamp_c)]=int(fb[row*framewidth+col]); //introducing a contrast check.  
					}
					if(int(fb[row*framewidth+col])<tcam[camno].frame.contr_min[j+(k*downsamp_c)]){
						tcam[camno].frame.contr_min[j+(k*downsamp_c)]=int(fb[row*framewidth+col]); //introducing a contrast check
					}
				}
			}
		}
	}
}

//blob_search function
//search through the sum matrix and find the brightest sums
//void blob_search(frame_info* frame, marker* marker, int num_markers, int contrast_min){
void blob_search(int camno, track_cam* tcam, int num_markers, int contrast_min, int downsamp_r, int downsamp_c){
	//frame->num_blobs=0; //innocent until proven guilty
	for(int i=0; i<num_markers; i++){
		int blob_val=0;
		for(int m=0; m<downsamp_r*downsamp_c; m++){
			if(tcam[camno].frame.sum[m]>blob_val && tcam[camno].frame.contr_max[m]-tcam[camno].frame.contr_min[m]>contrast_min){ //has to have a big contrast to be a blob (CONTRAST is user defined macro)
				blob_val=tcam[camno].frame.sum[m]; //the new max'
				tcam[camno].marker[i].downsamp_loc=m; //the sum integer (0-255)
				//frame->num_blobs++;
			}
		}
		tcam[camno].frame.sum[tcam[camno].marker[i].downsamp_loc]=0; //kill the one we just found so we can find the next biggest one.
	}
}

//brightest_pix_search function
//search through the blobs for the brightest pixel
//void brightest_pix_search(unsigned char * fb, frame_info* frame, marker* marker, int num_markers, int framewidth, int downsamp, int downsamp_w, int downsamp_h){
void brightest_pix_search(unsigned char * fb, int camno, track_cam* tcam, int num_markers, int framewidth, int downsamp_r, int downsamp_c, int downsamp_w, int downsamp_h){
	//br_pix_info[0] is the row
	//br_pix_info[1] is the col
	//br_pix_info[2] is the value
	for(int i=0; i<num_markers; i++){
		tcam[camno].marker[i].br_pix_val=0; //always has to start low
		for(int row=int(floor(tcam[camno].marker[i].downsamp_loc/downsamp_c))*downsamp_h; row<int(floor(tcam[camno].marker[i].downsamp_loc/downsamp_c))*downsamp_h+downsamp_h; row++){
			for(int col=tcam[camno].marker[i].downsamp_loc%downsamp_c*downsamp_w; col<tcam[camno].marker[i].downsamp_loc%downsamp_c*downsamp_w+downsamp_w; col++){
				if(int(fb[row*framewidth+col])>tcam[camno].marker[i].br_pix_val){ //if it is greater than the brightest pixel then store its info
					tcam[camno].marker[i].br_pix_row=row; //save the row
					tcam[camno].marker[i].br_pix_col=col; //save the column
					tcam[camno].marker[i].br_pix_val=int(fb[row*framewidth+col]); //save the value
				}
			}
		}
	}
}

The blocking (or blobbing) and search algorithm yields the estimated location of the brightest pixel in the image. This is passed to a specialized array-growth region growing algorithm which dynamically expands a region around the suggested brightest pixel to include all pixels that are within a threshold of brightness to the brightest. The region growing algorithm then computes the center of mass from the list of pixel coordinates, which are then passed to the PD and target location routines.

void region_grow(unsigned char * src, unsigned short* dest, 
		int w, int h, int b_r, int b_c, double* c_r, double* c_c){
	//need to do an expansion from the brightest point. 
	//this is sorta a random-access op - which is bad. 
	unsigned short fill = 0xff00; 
	int n = 0; 
	short r, c; 
	int  i, p; 
	unsigned char thresh = 20 ; 
	unsigned char brightest = src[w*b_r + b_c]; 
	g_rows[n] = b_r; 
	g_cols[n] = b_c; 
	n++; 
	int sta = 0; 
	int end = 0; 
	int lim = sizeof(g_rows)/sizeof(int); 
	while(n < lim && n > sta){
		//loop through all the new points, adding to the set as we go. 
		end = n; 
		for(i=sta; i < end; i++){
			r = g_rows[i]; 
			c =  g_cols[i]; 
			r++; //down
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			r -= 2; //up.
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			r++; //center
			c++; //to the right. 
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
			c-=2; //to the left. 
			if(r >= 0 && r < h && c >= 0 && c < w && n < lim){
				p = r*w +c; 
				if(brightest - src[p] < thresh){
					src[p] = 0; 
					dest[p] = fill; 
					g_rows[n] = r; 
					g_cols[n] = c; 
					n++; 
				}
			}
		}//end loop over past points. 
		sta = end; 
	}
	//calculate the center of mass. 
	double cm_r = 0; 
	double cm_c = 0; 
	for(i=0; i<n; i++){
		cm_r += g_rows[i]; 
		cm_c += g_cols[i]; 
	}
	cm_r /= n; 
	cm_c /= n; 
	*c_r = cm_r; 
	*c_c = cm_c; 
	//printf("point: %f %f %d \n",  cm_r, cm_c, g_frame++); 
	int cm_r_i, cm_c_i; 
	cm_r_i = (int)cm_r; 
	cm_c_i = (int)cm_c; 
	if(cm_c_i >= 0 && cm_c_i < w && cm_r_i >= 0 && cm_r_i < h)
		dest[cm_r_i*w + cm_c_i] = 0xffff; 
}

And that is, roughly, the entirety of the video tracking program! (Most of the rest of the code deals with the firewire bus and other less interesting details.) We conclude with a picture of the whole setup in the office.

{644}
hide / / print
ref: -0 tags: ME270 optical power date: 12-03-2008 22:25 gmt revision:17 [16] [15] [14] [13] [12] [11] [head]

Section 2: Microcontroller & microstepping

As mentioned before, we chose MSP430F5438 100-pin 16 bit microcontroller because it offers sufficient timers and speed for our problem and because we were both familiar with the architecture. Four 16-bit timers are used to control microstepping mirror tilt and pan, since the stepper motors have two phases. The microcontroller only needs to provide digital signals; current is provided through H-bridge drivers in the control board of the mm-150 - the DIPs with heat sinks below.

Opposite sides of the H-bridge are driven via hex inverters; hence, we only have to supply two PWM signals per motor, one per phase. Setting the PWM duty cycle to 50% will set the motor phase current to zero; by vectoring the duty cycle proportional to the sine and cosine of theta, where theta is the orientation of the motor * number of poles of the stepper, you can control microstepping. That, of course, is simplified; in practice, there are many details to contend with, namely:

  • The MSP430 is a 16 bit integer processor; hence, fractional values must be represented as fixed-point numbers. We chose 11-bit fixed point to optimize resolution and prevent overflow.
  • There is no divide. Division can be accomblished via bit-shifts (which is equivalent to dividing by 2), and addition.
  • There is one 16*16 -> 32 bit multiplier used as a peripheral in the MSP430 architecture, but the standard C library does not access it properly for our fixed-point math.
  • We have to approximate sine and cosine using fixed-point math, since the standard C library Sin and cos each take more than 2500 cycles -- too long when the microcontroller is only running at 12Mhz, and we want to update 4 microstepping phases at ~ 40Khz.

{646} hide/ /

We approximated sine and cosine, needed to vector the stepper motor phase currents, in fixed-point arithmetic first in C on linux - where the results could be plotted in matlab - before converting to MSP430 code. Since the trigonometric functions are repeating, we only need a polynomial approximation of sine from 0 to pi/2. The taylor series for sine is

 sin(x) = x - x^3/3! + x^5/5! - x^7/7! ...
; a quick check in matlab showed that the first three terms are enough to get an accurate approximation in the domain of interest. The MSP430 does not have division, however, so we approximated 1/3! = 1/6 as (1/8 + 1/32 + 1/128) and 1/5! = 1/120 as 1/128; division by powers of two is possible with right bit-shift operations. We chose base 11 (5 bits whole, 11 bits fractional) representation to avoid overflow: if 2^11 -> 1, we need to represent (pi/2)^5 -> 9.5 ; ceil(log_2(9.5)) = 4 (plus one bit for safety). The C program below shows this test.

#include <stdio.h>

char qsin(short i){
       //i goes from  0 pi/2 base 11 or...
       // 0 to 3217
       unsigned int cube, fifth, result;
       cube = (i*i) >> 11;
       cube = (cube*i) >> 11; //max = 7937
       fifth = (cube*i) >> 11;
       fifth = (fifth*i) >> 11; // max = 19585
       //our approximation to sine based on taylor series:
       //original: sin(x) = x - x^3/3! + x^5/5!
       //sin(x) = x - x^3*(1/8+1/32+1/128) + x^5*(1/128)
       result = (unsigned int)i -
               ((cube >> 3) + (cube >> 5) + (cube >> 7)) + (fifth >> 7);
       //result is base 11.  need it to be base 7.
       result = result >> 4;
       if(result > 127) result = 127;
       return (char)result;
}
//this is tricky, as it involves shifts, x-inversions, and y-inversions. 
//but it all makes sense if you plot out the respective functions. 
char isin(short i){
       // i is base 2^11
       //but we accept 0 to 2*pi or 12867
       if(i >= 0 && i < 3217) return qsin(i);
       else if(i >= 3217 && i < 6434) return qsin(6434 - i);
       else if(i >= 6434 && i < 9651) return -1*qsin(i - 6434);
       else if(i >= 9651 && i < 12867) return -1*qsin(12867 - i);
       else return 0;
}
char icos(short i){
       // i is base 2^11
       //but we accept 0 to 2*pi or 12867
       if(i >= 0 && i < 3217) return qsin(3217 - i);
       else if(i >= 3217 && i < 6434) return -1*qsin(i - 3217);
       else if(i >= 6434 && i < 9651) return -1*qsin(9651 - i);
       else if(i >= 9651 && i < 12867) return qsin(i - 9651);
       else return 0;
}

int main(void){
	short i; 
	for(i=0; i<12867; i++){
		printf("%d\t%f\t%d\t%d\n", i, ((float)i)/2048.0, (int)(isin(i)), (int)(icos(i))); 
	}
	return 0; 
}

We compiled and ran this program on the command line:

 gcc integer_trig.c 
 ./a.out > test.txt

Then we imported the data into matlab and plotted (Actual double floating-point sine and cosine are plotted on the same axis as thin black and magenta lines, respectively)

Later, we had to change the naive standard implementation of multiply to assembly to properly implement the fixed-point arithmetic - the MSP430's standard library did not implement the 16x16 multiply followed by shift correctly (it only keeps the bottom 16 bits). Note: this assembly function is for use with Code-Composer Studio, available from the Texas Instruments website. It seems that the IAR compiler uses different assembly syntax.

;*******************************************************************************
            .cdecls C,LIST,"msp430x54x.h"  ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Progam Start
;-------------------------------------------------------------------------------
                       
          ;;.sect "mply_11"
          ;;.asmfunc "mply_11"
                        .global mply_11 ;; this MUST BE PRECEDED BY TABS !!!!!

mply_11: 
        PUSH	SR	; 
         DINT		; turn off interrupts here. 
         NOP			; required after DINT
         MOV.W	R12, &MPY ; load the first operand. 
         MOV.W	R13, &OP2 ; load the second operand & start multiplication. 
         MOV.W	&RESLO, R12 ; low to R12 (this is the return value)
         MOV.W	&RESHI, R13 ; high to R13
         RRA.W R12 ; 1
         RRA.W R12 ; 2
         RRA.W R12 ; 3
         RRA.W R12 ; 4 
         RRA.W R12 ; 5
         RRA.W R12 ; 6
         RRA.W R12 ; 7
         RRA.W R12 ; 8
         RRA.W R12 ; 9
         RRA.W R12 ; 10
         RRA.W R12 ; 11
         
         RLA.W R13 ; 1
         RLA.W R13 ; 2
         RLA.W R13 ; 3
         RLA.W R13 ; 4
         RLA.W R13 ; 5
         
        ;; r14 can be clobbered across a function call, according to the msp430 ABI
        MOV.W	#0x001f, R14
        AND.W	R14, R12 ; mask off all but the bottom 5 bits from RESLO
         ADD.W	R13, R12 ; add (logical OR) the results. R12 is the 11-bit fixed point result.
         POP.W 	SR	;
         RETA		; return from subroutine.

            .end

Note the MSP430 does not have an opcode for multiple arithmetic shifts, nor does it have code for logical shifts - hence the need for repeated shifts and bitmasks!

{624}
hide / / print
ref: notes-0 tags: elektralite mm150 optical power light ME270 project date: 12-03-2008 20:39 gmt revision:5 [4] [3] [2] [1] [0] [head]

Section 1 : Reverse-engineering the light, part selection

Rather than engineering our own articulated spotlight, we elected to buy a moving-mirror DJ light; creating our own light source would simply have taken too much time, and demanded optical experience that we lack. After a brief survey, we bought an Elekralite mm150 (moving mirror, 150W bulb) DJ light, one of the cheapest on the market ($650); despite this, it is very well constructed, as you will see below. The light was originally controlled through the stage-specific DMX bus, but the possibility of directly controlling the light through this was discarded after we learned that the resolution on each axis is only 8 bits (+- 127); given the large range of the pan mirror, this is insufficient for tracking. Hence we decided to reverse engineer the light to determine the best way to directly control the mirror and shutter.
  • Overview, with dichroic color filter wheel and globos removed. We ended up putting these back in, as without them the unit does not initialize properly.
  • Another view with the shell taken off. The white ballast on the bottom powers the 150W HMI metal-halide bulb, along with a stabilization capacitor (to the left of the ballast) and starter (below the capacitor). The starter produces 2kV to initially ionize the gas in the bulb; there is no third starter electrode as in mercury vapor bulbs, as this would be a point of stress in the high-pressure (90atm) fused quartz arc tube. The bulb is on whenever the unit is plugged in, and the light output is controlled via the shutter. The top large transformer (+20V, +12V) is used to drive the display/control unit (left center) and the 6 stepper motors in the lamp, which are:
    • mirror tilt
    • mirror pan
    • shutter
    • globo selection
    • globo rotate
    • colorwheel
    • Detail of the breakout board for the 6 stepper motors, with the colorwheel stepper above it. The stepper motors are two-phase, permanent-magnet rotor types; we're not sure of the steps/revolution yet, though they all seem different. The breakout board also has attachments for the hall-effect sensors to detect orientation of the globo and color wheels.
    • The dichroic mirror color wheel. Regular filters would undoubtedly melt here - a pencil put into the beam of the HMI lamp will light on fire!
    • The globo wheel. Each globo is mounted to a gear which engages a center gear on the same axis as this plate. This center gear is driven by the globo rotate stepper motor.
    • Dichroic IR filter. Note that since it is viewed at an angle, the reflective wavelength goes up, and so you can see a slight red tint in the reflections off this. Removed this, since silicon photovoltaic cells respond to near IR energy.
    • Stepper motor controller. The three chips at the bottom are NXP 87LPC768 OTP microcontroller. Each can control two stepper motors, and each has an internal program for self-calibration using either the hall-effect sensors or hard mechanical limits on motor range. Upper chip is for the mirror (U3). These chips are controlled via one high-speed serial bus from the upper control board (the one with the LED display). The six upper chips, with heat-sinks on them, contain dual H-bridges, probably similar to the Allegro A3955 PWM microstepping motor driver. Between them are two standard 74HC04 hex inverters to drive the opposite leg of the h-bridges (each 87LPC768 has four outputs, two per motor, whereas each motor requires four inputs, two per phase. In this way, you can switch the direction of current flow through each motor phase with a single +20v supply rail.)
    • The Elekralite mm150 without the two control boards, globo wheel, or filter wheel. You can see the lamp, focus adjustment screws and reflector. Below the lamp is a 24V radial fan.
    • The Elektralite powered on, with globo and filter wheel back in place. The lamp is very, very bright!
    • Close-up of filter and globo wheels. The shutter has been removed; it fits on the shaft just above the long hex spacer. Just above that is the mechanical hard stop for the shutter.
    • The pin on the main controller that is used to control the 6 stepper axes. We tried probing it for some time, but could not directly figure out the serial protocol without a good logic analyzer (which is at home), so decided to implement our own microstepping PWM controller, and drive the inverters / H-bridges driectly.
    • The shutter, after being used for a good bit. The UV and IR from the lamp (mostly the IR, I think - the shutter gets really hot!) bleaches the black anodization on this bit of aluminum. We've drilled a 1/4" hole in one side to try to get a more tightly-collated beam.
    • The PWM waveform at the motor for the two phases (the glare at the left is from the light, which was of course on!). The other leads in the motor are simply the inverse of these via the 74HC04. For vector control like this, a 50% on/50% off PWM effectively sets the phase current to zero (the motor has sufficient leakage inductance at the 16kHz PWM frequency to keep di/dt low over multiple PWM periods). Hence, to control the motors we need something like:
      phase1 = 0.5*sin(theta) + 0.5 ; phase2 = 0.5*cos(theta) + 0.5
      , where theta is changed based on the control algorithm, and phase is scaled and used to set the PWM counter compare register. See below.
    • Microstepping control scheme based on vector control of current in the two phases of these stepper motors. As before, current will be regulated via PWM @ 16kHz, as the Elektralite engineers do, as opposed to linear current control. To generate the appropriate 6 PWM signals (mirror pan, mirror tilt, and shutter), we used a MSP430 microcontroller with 3 16-bit counters and 5+ capture-compare registers.
    • We used a MSP430F5xxx development board from TI -- see the next section. The device features sufficient timers and PWM outputs to control the stepper motors in the Elekralite. We will control motion of each using a simple up-down toggling via the parallel port to increment/decrement the motor theta variable. The microcontroller will need a look-up table or algorithm for calculating the sines and cosines of rotor angles.
    • small solar cell from Spark Fun Electronics. When placed in the beam of the light, it is possible to generate 500ma short-circuit current and 5V open-circuit voltage, but not at the same time. In a solar cell composed of a series of junctions, such as this, the total current at full voltage is limited by the minimum current from each of the junctions (they are in series!). Therefore to get maximum current you need very uniform illumination, something that is normally not difficult with the sun, but which will be difficult in this application. To avoid this problem we will try to procure higher efficiency single-junction GaAs concentrator cells, which can be up to ~40% efficient (as compared to this one, which is ~15% efficient).

{183}
hide / / print
ref: Isoda-2007.02 tags: SMA saccade basal_forebrain executive function 2007 microstimulation SUA cortex sclin date: 10-03-2008 17:12 gmt revision:2 [1] [0] [head]

PMID-17237780[0] Switching from automatic to controlled action by monkey medial frontal cortex.

  • SCLIN's blog entry
  • task: two monkeys were trained to saccade to one of two targets, left/right pink/yellow. the choice was cued by the color of the central fixation target; when it changed, they should saccade to the same-colored target.
    • usually, the saccade direction remained the same; sometimes, it switched.
    • the switch could either occur to the same side as the SUA recording (ipsilateral) or to the opposite (contralateral).
  • found cells in the pre-SMA that would fire when the monkey had to change his adapted behavior
    • both cells that increased firing upon an ipsi-switch and contra-switch
  • microstimulated in SMA, and increased the number of correct trials!
    • 60ua, 0.2ms, cathodal only,
    • design: stimulation simulated adaptive-response related activity in a slightly advanced manner
    • don't actually have that many trials of this. humm?
  • they also did some go-nogo (no saccade) work, in which there were neurons responsive to inhibiting as well as facilitating saccades on both sides.
    • not a hell of a lot of neurons here nor trials, either - but i guess proper statistical design obviates the need for this.
  • I think if you recast this in tems of reward expectation it will make more sense and be less magical.
  • would like to do shadlen-similar type stuff in the STN
questions
  1. how long did it take to train the monkeys to do this?
  2. what part of the nervous system looked at the planned action with visual context, and realized that the normal habitual basal-ganglia output would be wrong?
    1. probably the whole brain is involved in this.
    2. hypothetical path of error trials: visual system -> cortico-cortico projections + context activation -> preparatory motor activity -> basal ganglia + visual context (is there anatomical basis for this?) -> activation of some region that detects the motor plan is unlikely to result in reward -> SMA?

____References____

{293}
hide / / print
ref: Serruya-2002.03 tags: BMI Donoghue 2002 Hatsopoulos Utah array Serruya date: 09-07-2008 19:08 gmt revision:1 [0] [head]

PMID-11894084[0] Instant neural control of a movement signal.

  • used only a few (7-30) motor cortex neurons
  • this let the monkey immediately manipulate a computer cursor, without extensive training (according to them).

____References____

{502}
hide / / print
ref: notes-0 tags: nordic nrf24L01 state diagram flowchart SPI blackfin date: 06-25-2008 02:44 gmt revision:7 [6] [5] [4] [3] [2] [1] [head]

Outline:

The goal is to use a nRF24L01 to make an asymmetrical, bidirectional link. The outgoing bandwidth should be maximized, ~1.5mbps, and the incoming bandwidth can be much smaller, ~17kbps, though on both channels we want guaranteed latency, < 4ms for the outgoing data, and < 10ms for the incoming data. Furthermore, the processor that is being used to run this, a blackfin BF532, does not seem to play well when both SPI DMA is enabled and most CPU time is being spent in SPORT ISR reading samples & processing them. Fortunately, the SPI port and SPORT can be run synchronously (provided the SPI port is clocked fast enough), allowing the processor to run one 'thread' e.g. no interrupts. It seem that with high-priority interrupts, the DMA engine is not able to service the SPI perfectly, and without DMA, data comes out of the SPI in drips and drabs, and cannot keep the radio's fifo full. Hence, must program a synchronous radio controller, where states are stored in variables and not in the program counter (PC register, saved upon interrupt, etc).

As in other postings on the nRF24L01, the plan is to keep the transmit fifo full for most of the 4ms allowed by the free-running pll, then transition back into either standby-I mode, or send a status packet. The status packet is always acknowledged by the primary receiver with a command packet, and this allows both synchronization and incoming bandwidth. Therefore, there are 4 classes of transfers:

  1. just a status packet. After uploading, wait for TX_DS IRQ, transition to RX mode, wait for RX_DR irq, clear ce, read in the packet, and set back to TX mode.
  2. one data packet + status packet. There are timeouts on both the transmission of data packets and status packets; in this case, both have been exceeded. Here TX data state is entered, the packet is uploaded, CE is asserted, send the status packet, wait for IRQ from both packets. This requires a transition from tx data CE high state to tx status CSN low state.
  3. many data packets and one status packet. This is the same as above, only the data transmission was triggered by a full threshold in the outgoing packet queue (in processor ram). In this case, two packets are uploaded to the radio before waiting for a TX_DS IRQ, and, at the end of the process, we have to wait for two TX_DS IRQs after uploading the data packet.
  4. many data packets. This is straightforward - upload 2 packets, wait for 1 TX_DS IRQ, {upload another, wait for IRQ}(until packets are gone), wait for final IRQ, set CE low.

screenshot of the derived code working (yea, my USB logic analyzer only runs on windows..yeck):

old versions:

{568}
hide / / print
ref: notes-0 tags: perl slurp a2a date: 04-07-2008 04:52 gmt revision:3 [2] [1] [0] [head]

My friend wanted to grab a whole bunch of data from a historical database site, http://www.a2a.org.uk/ . He was paying a person to manually copy all the records into excel (for a rather low fee, too, $150), and the guy was having a problem entering the rupee amounts, since it seems that in this historical data, currency is denominated my Rs xx-yy-z, where xx is rupees, yy are 1/16 rupee, and z is 1/64 of a rupee (cool base 2 system for currency, no?).

Neverminding the currency detail, I told him that I could easily write a script to screen-scrape this data and export it to a CSV file. For reference, here it is:

#!/usr/bin/perl

$narg = $#ARGV + 1; 
if( $narg ne 1 ){
	print "please specify the file to read"; 
}else{
	$source = $ARGV[0]; 
	local( $/, *FH ) ;
	open(FH, $source); 
	$/ = "FILE"; 
	@j = <FH>; #slurp entire file, split on 'FILE'
	close FH; 
	#print "num\tcase\tplaintiff\tdefendant\tior\tdatestart\tdateend\tclaim\tr1\tr2\tr3\tcountry1\tcountry2\n"; 
	foreach $l (@j){
		# try to match the line..
		# match must be robust, as some of the records are incomplete. 
		my $case = ""; 
		my $plaintiff = ""; 
		my $defendant = ""; 
		my $num = ""; 
		my $ior = ""; 
		my $datestart = ""; 
		my $dateend = ""; 
		my $claim = ""; 
		my $r1 = "0"; 
		my $r2 = "0"; 
		my $r3 = "0"; 
		my $cont1 = ""; 
		my $cont2 = ""; 
		$l =~ s/[\n\t]/ /g; # remove newlines &tabs.
		if($l =~ /Case\s([\d\/]+)([^<]+)/){
			$num = $1; 
			$case = $2; 
			$case =~ s/^: //; #remove leading colon space.
			if($case =~ /\(([^\)]+)\)[^\(]+\(([^\)]+)\)/ ){
				$cont1 = $1; 
				$cont2 = $2; 
			}
			#remove the countries (in parenthesis)
			$case =~ s/\([\w ]+\)//g;
			if($case =~ /(.+(?= v )) v (.+)/){
				$plaintiff = $1; 
				$defendant = $2; 
			}
			if($case =~ /(.+(?= v\. )) v\. (.+)/){
				$plaintiff = $1; 
				$defendant = $2; 
			}
		}
		if($l =~ /IOR([^<]+)/){
			$ior = $1; 
		}
		if($l =~ /date: <\/b>([^-]+)-([^<]+)<\/font>/){
			$datestart = $1; 
			$dateend = $2; 
		}elsif($l =~ /date: <\/b>([^<]+)<\/font>/){
			$datestart = $1; 
		}
		if($l =~ /Claim<\/span>([^<]+)/ ){
			$claim = $1;
			$claim =~ s/(\d),(\d)/$1$2/g; #remove commas from numbers.
			if($claim =~ /Rs\.* (\d+)[-\.](\d+)[-\.](\d+)/i){
				$r1 = $1; 
				$r2 = $2; 
				$r3 = $3; 
			}elsif($claim =~ /Rs\.* (\d+)[-\.](\d+)/i){
				$r1 = $1; 
				$r2 = $2; 
			}elsif($claim =~ /Rs\.* (\d+)/i){
				$r1 = $1; 
			}
		}
		if($num ne ""){
			print "$num\t$case\t$plaintiff\t$defendant\t$ior\t$datestart\t$dateend\t$claim\t$r1\t$r2\t$r3\t$cont1\t$cont2\n"; 
		}
	}
}

run it with > , e.g.

./a2a_extract.pl document.html > out1.csv
where document.html is saved from the web browser.

{552}
hide / / print
ref: notes-0 tags: CO2 global warming carbon dioxide indonesia brazil date: 03-14-2008 21:34 gmt revision:0 [head]

From the New Yorker, Feb 25:

  • "Just two countries - Indonesia and Brazil - account for ten percent of the greenhouse gasses released into the atmosphere. "
  • "During the next twenty-four hours the effect of losing forests in Brazil and Indonesia will be the same as if eight million people boarded airplanes at Heathrow airport and flew en mass to New York. "

{544}
hide / / print
ref: notes-0 tags: energy carbon CO2 hot water heater. date: 02-25-2008 23:36 gmt revision:2 [1] [0] [head]

How much carbon dioxide (CO2) is released to heat the water for a 5-minute shower?

  1. assumptions
    1. water enters your house at 45F, and you heat it to 100F.
    2. the energy efficiency of your hot water heater is 87%, and we ignore the cost of static thermal losses.
    3. you live in the southeast like me, which is predominantly powered by coal-fired plants. These plants release about 0.8kg/kwh of CO2 ref
    4. transmission of energy from the power plant to your home is 90% efficient
    5. you have a shower head that flows at a rate of 2.2 gallons/minute
  2. result: 2.2gpm -> 138.6 ml/sec -> * 31C temp rise -> 4.2kw -> 0.31kg CO2.
    1. that's about equivalent of driving 4 miles in a 30mpg car. (gasoline CO2 release = 2.4kg/gallon)

  • Interesting analysis. I'm surprised how much CO2 is used by those 5-minutes of delicious, delicious hot shower! --joeyo

{377}
hide / / print
ref: engineering notes-0 tags: bluetooth CSR NXP headset radio telemetry 802.11 zigbee low-power date: 12-12-2007 06:10 gmt revision:26 [25] [24] [23] [22] [21] [20] [head]

the contenders:

  • NXP BGB210S, a 4th generation chip from Philip's spin-off NXP.
    • 3 x 5 x 1 mm (!!).
    • supports Bluetooth 2.0 + EDR.
      • the higher data rate is really targeted at decreasing the TX active time.
    • power consumption: 12ma @ 1.8v supply = 21.5mW
    • CMOS w/ near-zero intermediate frequency radio.
  • BGW211 802.11 system-on-a-chip, from NXP
    • 400mw Tx power, 300mw Rx - both too much, me thinks.
  • BCM4326
    • similar power figures (295mw rx, 425mw tx)
    • ultra-small 0.25mm WLCSP (!!)
    • one chip solution for 802.11b/g ; BCM4328 supports 802.11a, too.
  • Wi2wi w2cbw003 - 230ma tx, 210ma rx 802.11 module. too much.
  • G2 Microsystems , developers of 802.11B (11mbps) system-on-a-chip for RFID.
    • insanely low power dissipation! years on AA batteries! (based on 40s interval between data transmissions. 1.3mJ per transmission - an order of 500 lower than existing solutions. much lower static dissipation, too.
    • includes 32 bit RISC processor with 80kb ram, 320 kb flash/rom.
    • works with existing infrastructure, e.g. cisco.
    • article on the chip / product, may 2006.
    • http://www.gainspan.com/ -- competitors. they do not appear to have a product yet.
  • Freescale LP1070FC 802.11a/b/g, requires external PA, LNA, switch. no data on the power consumption... actually, the datasheet appears to be rather incomplete!
  • CSR UniFi-1 radio is far better, but I can't seem to find documentation for that, specifically the power dissipation.
    • well, let's see - 20 hours talk time with a 1500mAH battery = 75ma. not bad, i guess; TX power can be decreased for the short range we need.
  • BlueCore5 ; product brief, which includes more power info.
    • rather recently developed; is the silicon debugged? The datasheet is preliminary information.
    • 10 x 10mm, 0.8mm pitch 105 balls or 8x8 TFBGA.
    • 1.5V core, 1.8V-3.6V io, USB
    • bluetooth v2.0/2.1.
    • 64mips DSP on-chip.
      • 0.3 mA/MIPS at 1.5V. compare to Texas instruments TMS320VC5507 = 0.45ma/Mhz @ 1.2V core ~= 54Mw at 100mips; Kalimba ~= 30mw @64mips.
      • this is 2mips/channel. enough? damn, gotta keep the power low!
      • the Bluecore3 datasheet has more information on the DSP power consumption.
    • 16 Mbit flash, too!
    • BlueCore4 seems to be much better documented, but it does not include the DSP, which saves a lot on parts count.. as well as power.
  • Bluecore4
    • 8x8mm 96-bga,
    • with 6mbit flash!
    • bluetooth 2.0 / EDR.
    • current consumption of about 26ma @ 1.8V supply when in SCO HV3
  • Boroadcom BCM4326
    • single chip 802.11b/g solution, integrated Arm7 CPU
    • again, 300mW (not mA! smaller!) Rx, 400 mW Tx. That's still a lot of power.
  • Broadcom BCM2047
    • again, seems that these have yet to come out; details are scarce.
    • The belkin bluetooth 2.0 adapter that I bought at compusa uses a BCM2045.
  • CC2400, non-bluetooth - simpler!
  • Zarlink - ultra low power, 433Mhz ISM band biomedical tranciever.
    • about 7x7mm.
    • 3v supply, 2.7 should work, 5ma = 13.5mw (yesss!)
    • 800kbps raw data rate, max.
    • 2.45Ghz wakeup reciever (??)
    • seems to be designed for pacemakers & neurostimulators.
    • need to contact zarlink for the full data sheet.
  • RFM TR1100 - what the wolf lab uses for telemetry. OOK or ASK.
    • 1Mbps max.
    • only 1 channel, so far as i can tell...
    • 8ma @ 2.7V = 21.6mw.
    • integrated SAW filters = narrow bandwidth.
    • 10 x 6 mm size, minimal external components, though it does seem to require extra resistors.
    • really interesting method of obtaining RX input amplification stability - a SAW delay line, where the amplifiers are pulsed on at different times to permit the passage of RF energy. quote: "rf stability is obtained by distributing RF gain over time", as opposed to the superheterodyne solution of distributing gain over frequencies. If there were 100db of gain in 1 frequency, the amplifier is very likely to oscillate.
  • RFM TRC101
  • RFM TR3100 576 kbps ASK, -85dbm 10e-3 error rate.
    • 10ma TX / 7ma RX
    • 11x9,65mm SM-20L package
    • kinda has a lot of external components.
    • 434 mhz operation.
  • ADF7025 Analog 431-464, 862-870, 902-928 ISM band FSK transceiver.
    • 20ma TX (28ma at +10dbm) , 20ma RX from 2.3 to 3.6V supply.
    • direct conversion: zero IF.
    • SPI interface (plus a bunch of other signals).
    • 384kbps max data rate.
    • 7mm x 7mm 48 lead CSP
  • CC1101 (chipcon was acquired by TI)
    • 500kbps FSK, GFSK, MSK, OOK, ASK transmit/receive. 500kbps is only available in MSK, minimum-shift keying mode.
      • -84dbm receiver sensitivity @ 500kbps.
    • same bands as above + a bit more margin.
    • suitable for frequency hopping systems.
    • QLP 4mm x 4mm package
    • 16ma TX (32.3 at +10dbm), 16ma RX
    • 1.8 - 3.6V operation.
  • Freescale MC13192, Zigbee compliant transciever, 2.405 - 2.480 Mhz, 5mhz channels, 2Mchip/sec over the air data rate, 200kbps practical rate.
    • 30ma TX @ 0dbm, 37ma RX.
    • 5mm x 5mm package
    • full Zigbee PHY support.
    • similar device from ember - 35ma TX / 35ma RX, 2.1-3.5V, 7x7mm, includes microprocessor.
    • MC13201 - also targeted at 802.15.4 compliance.
      • good to 250kbps, 5.0 mhz channels, DSSS, 2.0 - 3.4V,
      • requires external transmit/receive switch
      • 30ma TX / 37ma RX
      • 5 x 5mm package
  • TI / Chipcon CC2430 - 27ma TX / 27ma RX, with microcontroller, 7x7mm package, quick power-up.
  • Cypress wireless USB
    • 2.4ghz, 1mbps, DSSS encoding (like zigbee) -- DSSS reduces the data rate, of course; the data rate over the air is always 1mbps.
      • the favored rate is 8x DSSS, where each symbol encodes one byte (8 bits) but requires 32 or 64 chips for transmission (resulting in a net rate of 250kbsp or 125 kbps, like zigbee. )
    • 21ma normal operating current @-5dbm, 1.8V to 3.6V
    • 6mm x 6mm 40-lead package
    • document above is a generally good overview of the complexities of this type of design.
  • SC1211
    • 110kbps, UHF transceiver (~863 - 960mhz). very low power consumption in RX: 3ma / TX: 25ma @ +10dbm out
    • out November 2007.
    • competitor to below -- much lower RX power (and lower rate).
    • includes 64byte fifo, data whitening, etc.
  • advance info from Maxim
    • very low power TX: 4ma @ -10dbm, RX: 150ua Hey.. that's lower power than most PLL, VCO, & PA put together!
    • OOK, ~116kbps.
  • Nordic nRF24L01 - THE BEST (so far!)
    • datasheet.
    • 12ma TX/RX, 2.1 3.6V
    • 2mbps over-the-air rate, GFSK, 10m range (better with a bigger antenna)
    • 4x4mm 20 pin package.
    • 125 selectable channels.
    • allows clock sharing with a microprocessor, e.g. the blackfin, provided it exceeds the 60ppm specification.
    • 22ua power consumption in standby-1 mode (transition from this state to RX/TX in 130us), 320ua power consumption in standby-2 mode (ready to transition to TX)
      • it is important to never keep the nRF24L01 in TX mode for more than 4ms at a time (!)
    • i think the designer's confidence showes through the specification sheet: they are proud of the chip & it's specifications, which is a very good thing. it means they put some pride and passion into it.
    • development board - need to buy! They also [distribute the IC http://www.sparkfun.com/commerce/product_info.php?products_id=690], yay!

{504}
hide / / print
ref: bookmark-0 tags: blackfin BF537 uClinux webserver USB2 vmware date: 11-21-2007 22:32 gmt revision:0 [head]

http://www.camsig.co.uk/ -- blackfin is hot like chernobyl. 1" sq 600mhz webserver etc.

  • uses NET2272 high-speed USB-2.0 peripheral from PLX technology.
  • has a 10/100 ethernet mac w/o magnetics
  • 99 GBP
  • specsheet - no power consumption figures
  • attaches with a rubberized compression connector - no solder required!
  • Develop programs with a VMware virtual appliance (openSuSE 10.2) - brilliant! (though the download is HUGE ... and hosted by amazon)

{404}
hide / / print
ref: -0 tags: blackfin BF532 memory map date: 11-21-2007 21:18 gmt revision:1 [0] [head]

page 6 on the spec sheet. 55

{487}
hide / / print
ref: notes-0 tags: Nordic RD nrf24l01 problem transceiver date: 11-02-2007 18:00 gmt revision:4 [3] [2] [1] [0] [head]

here is the final, concluding, email i sent to nordic semiconductor concerning my 'troubles' with their chip. I post it here in hopes that it may help somebody else out there via the magic of the internet. See {485} for the development of the mode-switch solution (2) and {484} for the dropped packet investigation.


Hi xxx,

Ok, i figured out both of my problems:

  1. The missing RX_DR IRQ was because I was clearing the RX fifo upon reading outone packet. Because a packet was being received while the SPI was reading it out (the PTX is continually transmitting), this caused the radio to drop the packet before it was completely received. Dumb! dumb!
  2. Concerning my old problem of lost packets during mode switches, I needed to do a number of things to get it to work:
    1. Add inline resistors to keep spi noise out of the radio
    2. Increase the SPI clock on both PTX and PRX, to avoid not being able to read out the packet after one IRQ and before another was received (as you suggested below).
    3. Added a 62us (of course, longer delays also work) delay between transitioning from RX mode to TX mode. During this time I do not assert CE. A delay in for the opposite transition is not needed. Not exactly sure why this is needed, but it works!
    4. On the PRX, when i send the 'acknowlegement' packet, it is necessary to only pulse CE after uploading the packet. Holding CE high until TX_DS IRQ is asserted somehow messes things up. I guess this is described on the state diagram on your spec sheet - it is best to go back into standby-I mode not standby-II, as there is no transition to RX mode from standby-II.

As a result, I'm getting 99.99 % reliability on bidirectional bandwidth of 1.39mbps PTX->PRX and 18.3kbps PRX->PTX. So, I'm a happy person :) :) Hence, I don't have to try another radio solution.

Just wanted to pass the information along in case it would help your other customers.

cheers, Tim Hanson

{465}
hide / / print
ref: notes-0 tags: CRC32 ethernet blackfin date: 10-10-2007 03:57 gmt revision:1 [0] [head]

good explanation of 32-bit CRC (from the blackfin BF537 hardware ref):

{444}
hide / / print
ref: notes-0 tags: nordic pinout nRF24L01 spark fun electronics date: 10-09-2007 19:59 gmt revision:5 [4] [3] [2] [1] [0] [head]

nordic semi links:

here is the connection list for the nRF24L01 module made by sparkfunelectronics
  1. VCC
  2. CE
  3. CSN
  4. SCK
  5. MOSI
  6. MISO
  7. IRQ
  8. GND
(1 is by the voltage regulator, obviously.) reversed:
  1. GND
  2. IRQ
  3. MISO
  4. MOSI
  5. SCK
  6. CSN
  7. CE
  8. VCC

{437}
hide / / print
ref: bookmark-0 tags: I2S bust serial protocol DAC date: 08-27-2007 16:54 gmt revision:0 [head]

http://www.nxp.com/acrobat_download/various/I2SBUS.pdf

{432}
hide / / print
ref: notes-0 tags: James DeMarsh PHF tlh24 Cornell date: 08-21-2007 16:35 gmt revision:0 [head]

{428}
hide / / print
ref: notes-0 tags: activewire ez-usb an2131 cypress date: 08-16-2007 00:33 gmt revision:1 [0] [head]

to get the activewire board working under linux (debian):

  1. I had to install fxload (in the apt repository).
  2. install hex (1) , which is a simple LED blink routine from http://ezusb2131.sourceforge.net/ via:
    1. sudo fxload -I led2.hex -D /proc/bus/usb/006/118 where 118 is the address from dmesg | tail and led2.hex is hex(1)
  3. install hex (2), which is from http://activewire-osx.cvs.sourceforge.net/ -- it is the most recent i could find. translated via {427}
    1. sudo fxload -I awfirm2.hex -D /proc/bus/usb/006/118 awfirm2.hex is, of course, hex(2)
  4. check dmesg | tail - the EZ-USB chip should disconnect and reconnect with a new address. I don't know why the first ex is required - perhaps it resets the processor?
  5. run the awusb-linux program, for example, and do what you like.

I have no idea why this is required. perhaps my board is broken abit?

hex (1):

:03000000020100FA
:10010000907F947400F0907F9D7410F0907F9774AE
:1001100010F012012D12012D12012D907F97740005
:10012000F012012D12012D12012D02010C786490A4
:0C013000FB50A3E582458370F9D8F4224F
:00000001FF

hex(2):

:1007B600D204C203C200C202C201120653D2E843E7
:1007C600D820907FAB74FFF0907FA9F0907FAAF0BD
:1007D6005391EF907FAFE04401F0907FAEE0440D7F
:1007E600F0D2AF20014C750C00750B00750A007530
:1007F60009007F487E927D007C00AB0CAA0BA90AFB
:10080600A809C31207A5502020011D7A0079007897
:1008160000E50C2401F50CEA350BF50BE9350AF574
:100826000AE83509F50980CA2001B8D205120D7B00
:0F08360080B1300105120100C20112045180F39C
:010845002290
:10010000907FE9E070030201DF14700302025B24B8
:10011000FE70030202CF24FB70030201D9147003A6
:100120000201D31470030201C71470030201CD242D
:10013000056003020323120E33400302032F907F56
:10014000EBE024FE6016146040240270707403908B
:100150007FD4F07437907FD5F002032F907FEAE0D0
:10016000FF120A2D8B0D8A0E890FEA496011AE022B
:10017000EE907FD4F0AF01EF907FD5F002032F9087
:100180007FB4E04401F002032F907FEAE0FF120AFF
:100190007C8B0D8A0E890FEA496018AE02EE907FC3
:1001A000D4F0AF01EF907FD5F0120705907FB5F046
:1001B00002032F907FB4E04401F002032F907FB43C
:1001C000E04401F002032F120DFD02032F120E1F57
:1001D00002032F120E1702032F120DEF02032F122C
:1001E0000E35400302032F907FE8E0247F60241443
:1001F00060312402705BA200E433FF25E0FFA2021D
:10020000E4334F907F00F0E4A3F0907FB57402F0E8
:1002100002032FE4907F00F0A3F0907FB57402F00A
:1002200002032F907FECE0F45480FFC4540FFFE0F2
:1002300054072F25E024B4F582E4347FF583E0549D
:10024000FD907F00F0E4A3F0907FB57402F002030C
:100250002F907FB4E04401F002032F120E374003C9
:1002600002032F907FE8E024FE601D240260030259
:10027000032F907FEAE0B40105C20002032F907FB4
:10028000B4E04401F002032F907FEAE07038907FE1
:10029000ECE0F45480FFC4540FFFE054072F25E036
:1002A00024B4F582E4347FF583E4F0907FECE054ED
:1002B00080FF131313541FFFE054072F907FD7F0D4
:1002C000E04420F08069907FB4E04401F080601247
:1002D0000E39505B907FE8E024FE60182402704FD6
:1002E000907FEAE0B40104D2008044907FB4E044FF
:1002F00001F0803B907FEAE07020907FECE0F454C6
:1003000080FFC4540FFFE054072F25E024B4F5828A
:10031000E4347FF5837401F08015907FB4E04401EC
:10032000F0800C120C035007907FB4E04401F09071
:060330007FB4E04402F07E
:0103360022A4
:03003300020E2F8B
:040E2F0053D8EF3273
:100337001201000100000040540801010000010201
:1003470000010902C00001010080960904000004B1
:10035700FFFFFF00070581020200000705010240B9
:1003670000000705820202000007050202400000A4
:100377000904000100FFFFFF000904000200FFFF5E
:10038700FF000904000300FFFFFF00090400040049
:10039700FFFFFF000904000500FFFFFF000904003D
:1003A7000600FFFFFF000904000700FFFFFF000929
:1003B70004000800FFFFFF000904000900FFFFFF1A
:1003C700000904000A08FFFFFF0007058102020079
:1003D700000705010240000007058202020000072E
:1003E700050202400000070583020100000705031C
:1003F700020300000705040240000007050502404C
:10040700000004030904220341006300740069002B
:100417007600650057006900720065002C00200017
:1004270049006E0063002E001E0341006300740044
:1004370069007600650057006900720065002000BA
:0A04470055005300420000000000C1
:10065300907FDE740FF0907FACF0907FDF743FF0FB
:10066300907FADF0907FAE741FF0E4FF74802FF5A0
:1006730082E4347DF583E4F074002FF582E4347E64
:10068300F583E4F074802FF582E4347EF583E4F09F
:1006930074C02FF582E4347CF583E4F074402FF5C5
:1006A30082E4347DF583E4F074C02FF582E4347D75
:1006B300F583E4F074402FF582E4347EF583E4F0AF
:1006C3000FBF40A8E4907F9CF0907F9DF0907F9EA9
:1006D300F0907F93F0907F94F0907F95F0907F96C9
:1006E300F0907F97F0907F98F0751D01D200F51977
:1006F300F51AF518F51BF51CC206F516F517120EBB
:020703002722AB
:10045100907F9AE0907E80F0907F9BE0907E81F08B
:10046100907FB77402F0907F9DE0907E00F0907FC6
:100471009EE0907E01F0907FB97402F0907FCCE015
:1004810030E103020507907FBAE030E108E51C1571
:100491001C7002151B300669E4F50D907FCDE0FF5D
:1004A100E50DC39F5051E51AB40108E51C900FF00A
:1004B100F0800AE51B900FF0F0E51CA3F0051CE5A8
:1004C1001C7002051B74C0250DF582E4347CF58394
:1004D100E0FF74F0251AF582E4340FF583EFF0AFF5
:1004E10019E51A04FD7A0F7BF0120DBC7F0A7E001C
:1004F100120DD8050D80A4E4907FBBF0F516751799
:1005010008E4907FCDF0907FBAE030E10CA3E06089
:1005110008E51764084516704B30063DE51AB4012D
:1005210008E51C900FF0F0800AE51B900FF0F0E554
:100531001CA3F0051CE51C7002051BAF19AD1A7A4E
:100541000F7BF0120DBCAF197D027A0F7BF0120DFB
:10055100A0900FF0E0907D80F0907FBB7401F0E4FB
:05056100F516F517225C
:100BDA00907F9E74FFF0907F9DF0907F9CF0E49050
:100BEA007F98F0907F97F0907F96F0907F95F090A5
:090BFA007F94F0907F93F0D32268
:020AFD00D32202
:020E3300D322C8
:080E1700907FEAE0F51ED322F2
:0E0DEF00907F00E51EF0907FB57401F0D322D6
:080E1F00907FEAE0F515D322F3
:0E0DFD00907F00E515F0907FB57401F0D322D1
:020E3500D322C6
:020E3700D322C4
:020E3900D322C2
:100C0300907FE9E0B4B020907FECE0F45480FFC41F
:100C1300540FFFE054072F25E024B4F582E4347F1A
:090C2300F5837402F0C322D32210
:100C2C00C0E0C083C082C085C084C086758600D2F7
:100C3C00015391EF907FAB7401F0D086D084D085B6
:070C4C00D082D083D0E0321A
:100BB000C0E0C083C082C085C084C08675860090B6
:100BC0007FC4E4F05391EF907FAB7404F0D086D0F3
:0A0BD00084D085D082D083D0E032BB
:100C5300C0E0C083C082C085C084C086758600534F
:100C630091EF907FAB7402F0D086D084D085D08290
:050C7300D083D0E03247
:100C7800C0E0C083C082C085C084C086758600532A
:100C880091EF907FAB7410F0D086D084D085D0825D
:050C9800D083D0E03222
:010AFF0032C4
:100ABD00C0E0C083C082C085C084C086758600E555
:100ACD001D6004151D8002D2035391EF907FAB740E
:0F0ADD0008F0D086D084D085D082D083D0E0328C
:100C9D00C0E0C083C082C085C084C0867586005305
:100CAD0091EF907FA97401F0D086D084D085D08249
:050CBD00D083D0E032FD
:100CC200C0E0C083C082C085C084C08675860053E0
:100CD20091EF907FAA7401F0D086D084D085D08223
:050CE200D083D0E032D8
:100CE700C0E0C083C082C085C084C08675860053BB
:100CF70091EF907FA97402F0D086D084D085D082FE
:050D0700D083D0E032B2
:1008CA00C0E0C083C082C085C084C086758600C06F
:1008DA00D075D000C000C005C006C007E4FFFE9076
:1008EA007FC7E0FDC3EF9D7480F86E98502AEF3001
:1008FA00E0102440F582E4347EF583E0907F98F09E
:10090A00800F74402FF582E4347EF583E0907F9760
:10091A00F00FBF00010E80C7907FC7E4F05391EF3C
:10092A00907FAA7402F0D007D006D005D000D0D0AC
:0D093A00D086D084D085D082D083D0E0322A
:100D0C00C0E0C083C082C085C084C0867586005395
:100D1C0091EF907FA97404F0D086D084D085D082D6
:050D2C00D083D0E0328D
:10094700C0E0C083C082C085C084C086758600C0F1
:10095700D075D000C000C005C006C007907FC9E0B1
:10096700F508E4FFFE907FC9E0FDC3EF9D7480F8B2
:100977006E98501DEF30E00A907DC1E0907F9EF0A9
:100987008008907DC0E0907F9DF00FBF00010E8032
:10099700D4907FC9E4F05391EF907FAA7404F0D00C
:1009A70007D006D005D000D0D0D086D084D085D04F
:0609B70082D083D0E03283
:100D3100C0E0C083C082C085C084C0867586005370
:100D410091EF907FA97408F0D086D084D085D082AD
:050D5100D083D0E03268
:10084600C0E0C083C082C085C084C086758600C0F3
:10085600D075D000C005C006C007907D40E0FFC33C
:1008660013F519907FCBE0B40210751A01907D4103
:10087600E0751B00F51CD206801E907FCBE0C3946A
:10088600034015751A02907D42E0FE907D41E0FD21
:10089600EEF51BEDF51CD206907FCBE4F0907FBB06
:1008A600F0F5167517085391EF907FAA7408F0D0EB
:1008B60007D006D005D0D0D086D084D085D082D0BF
:0408C60083D0E032C9
:010E3B003284
:100D5600C0E0C083C082C085C084C086758600534B
:100D660091EF907FAA7410F0D086D084D085D0827F
:050D7600D083D0E03243
:010E3C003283
:1009BD00C0E0C083C082C085C084C086758600C07B
:1009CD00D075D000C000C005C006C007E4FFFE9082
:1009DD007FCFE0FDC3EF9D7480F86E98501DEF3012
:1009ED00E00A907C41E0907F9CF08008907C40E094
:1009FD00907F96F00FBF00010E80D4907FCFE4F072
:100A0D005391EF907FAA7420F0D007D006D005D077
:100A1D0000D0D0D086D084D085D082D083D0E032A3
:010E3D003282
:010E3E003281
:010E3F003280
:010E4000327F
:03004300020B00AD
:100B0000020C2C00020C5300020BB000020ABD00C4
:100B1000020C7800020AFF00020C9D00020CC200C9
:100B2000020CE7000208CA00020D0C00020947008F
:100B3000020D310002084600020E3B00020D560075
:100B4000020E3C000209BD00020E3D00020E3E00F6
:080B5000020E3F00020E4000FE
:100D7B00907FD6E054FBF0E04408F0300504E044EB
:100D8B0002F07FF47E01120DD8907FD6E054F7F07D
:050D9B00E04404F02219
:100DD8008E0E8F0FE50F150FAE0E7002150E4E60BA
:070DE80005120AEC80EE2267
:080E2700E4F526D2E9D2AF2266
:100B8500A907E5267023907FA5E04480F0E925E0DC
:100B9500907FA6F08D21AF03A9077522018A2389CD
:0B0BA50024E4F525752601D322C322AD
:100B5800A907E5267025907FA5E04480F0E925E007
:100B68004401907FA6F08D21AF03A9077522018A61
:0D0B7800238924E4F525752603D322C3222A
:03004B0002056645
:10056600C0E0C083C082C085C084C086758600C0D6
:10057600D075D000C000C001C002C003C006C007CD
:10058600907FA5E030E206752606020635907FA527
:10059600E020E10CE52664026006752607020635B2
:1005A600AF26EF24FE604814602C24FE60772404F6
:1005B6006003020635AB22AA23A924AF2505258FA1
:1005C6008275830012071E907FA6F0E525652170CF
:1005D6005E7526058059907FA6E0AB22AA23A92442
:1005E600AE258E8275830012074B7526028040E584
:1005F6002124FEB52507907FA5E04420F0E52114CF
:10060600B5250A907FA5E04440F0752600907FA6A8
:10061600E0AB22AA23A924AE258E82758300120799
:100626004B0525800A907FA5E04440F075260053CF
:1006360091DFD007D006D003D002D001D000D0D0B1
:0D064600D086D084D085D082D083D0E03221
:020A7C008F10D9
:100A7E00E4F5117512FF751304751409AB12AA1360
:100A8E00A91490000112071EB4031DAF110511EF3A
:100A9E00B51001221207057E0029FFEE3AA907754F
:0E0AAE0012FFF513891480D47B007A007900C2
:010ABC002217
:100A2D00E4FE7512FF751303751449AB12AA13A9D1
:100A3D001490000112071E6402702DAD060EEDB567
:100A4D0007012290000212076D85F010F51162105A
:100A5D00E5106211E511621029FDE5103AA9057541
:0E0A6D0012FFF513891480C37B007A00790014
:010A7B002258
:100DA000120B58E52624FA600E146006240770F32F
:0C0DB000D322E4F526D322E4F526D3225A
:100DBC00120B85E52624FA600E146006240770F3E6
:0C0DCC00D322E4F526D322E4F526D3223E
:100AEC007400F58690FDA57C05A3E582458370F91D
:010AFC0022D7
:03000000020E0BE2
:0C0E0B00787FE4F6D8FD7581260207B65A
:10070500BB010689828A83E0225002E722BBFE02F2
:09071500E32289828A83E4932225
:10071E00BB010CE58229F582E5833AF583E0225090
:10072E0006E92582F8E622BBFE06E92582F8E222DA
:0D073E00E58229F582E5833AF583E49322F4
:10074B00F8BB010DE58229F582E5833AF583E8F0E4
:10075B00225006E92582C8F622BBFE05E92582C890
:02076B00F22278
:10076D00BB0110E58229F582E5833AF583E0F5F0CA
:10077D00A3E0225009E92582F886F008E622BBFEA7
:10078D000AE92582F8E2F5F008E222E5832AF583ED
:08079D00E993F5F0A3E99322B2
:1007A500EB9FF5F0EA9E42F0E99D42F0E89C45F0AA
:0107B5002221
:00000001FF

{361}
hide / / print
ref: notes-0 tags: Clementine review organize Miguel 042707 movies videos date: 04-29-2007 19:13 gmt revision:14 [13] [12] [11] [10] [9] [8] [head]

things that I want to send to miguel:

{360}
hide / / print
ref: thesis-0 tags: clementine 042607 operant conditioning date: 04-27-2007 16:45 gmt revision:3 [2] [1] [0] [head]

tried 2d again... some success. looked at 29 (still good for x control, but not in BMI mode), channe 71 (still by default silent, correlated to behavior) channel 18 (did not work well) channel 84 (did not work) and channel 54 (like 71, highly correlated to behavior - not sure if the mk learned to control it). have videos etc.

channel 54, new for today and might, might be > 71.. though looking back at the videos, 71 seems pretty good. (it is also a bad idea to keep switching the game..) channels 54 and 71 are different from 29 in that 29 never goes completely silent; 71 goes silent when thew mk is paying attention, 54 when he is not moving. 29 can be modulated + and -, 71 and 54 just + (or so). of course, the monkey is usually in motion so both have high variance and silent periods are short-ish

channel 29, as always

channel 71, as before (very stable!)

channel 54

movies (in the order that they were taken):

{358}
hide / / print
ref: thesis-0 tags: clementine 042507 operant conditioning date: 04-25-2007 20:19 gmt revision:2 [1] [0] [head]

OK, today clementine played absolutely abysmally - he did practically nothing, though he did do pole control for a little bit. I think we must stop doing pole control - it is too easy, he must become accustomed to doing brain control from the beginning. Anyway, monkeys never like learning new things (compare to people!); I just have to give him more time. The units are stable (in my agitated state, i forgot to make screenshots). Channel 54 might be very excellent for brain control - however, i did not test it today. If it is still there tomorrow, i will try.

http://m8ta.com/tim/clem042507_trainY.MPG (ignore the first few seconds - he was not trying so hard/was not paying attention)

{356}
hide / / print
ref: thesis-0 tags: clementine 042407 operant conditioning date: 04-25-2007 00:21 gmt revision:1 [0] [head]

Today, as yesterday, I tried operantly conditioning primary units on channels 29 (x) and 71 (y) for BMI control. The first few minutes were run in pole control for Miguel's visitors, but i did not save the data. Again as before the monkey was not quite motivated to perform the task. Tomorrow he ought to be thirsty - & I'll try to start him on 2d control after tweaking the gain and offset parameters on the individual axes. During 2d control tomorrow the target size should be expanded also to about 3 to keep the monkey's interest.

There seems to be a bug in the BMI- when two units are sorted, both contribute to the firing rate estimate. I noticed this during X control today, which somewhat decreased the performance. Y performance was slightly better than yesterday, but still not great - he hasn't quite figured it out yet. XY was shitty, i guess.

Among other things, I really need to test the recording system - perhaps make a new file format that is extensible yet compressed? maybe labeled data streams? something like plexon files? Or perhaps just record it to the analog files (that would be easy!) nahh. todo:

  • write some matlab to combine the SQL records.
  • record the unit # in waveform record
  • save the logger output into the SQL db - not just in a file as now.
  • fix the onscreen shapes.

channel 29, at the end of the session:

channel 71. both these channels seem very stable - I hope the mk gets it before the evaporate!

there are no bmisql outputs as I did not run this analysis.

movies:

{355}
hide / / print
ref: thesis-0 tags: clementine 042307 operant conditioning date: 04-24-2007 01:37 gmt revision:2 [1] [0] [head]

Today, once again, I tried BMI both via pole control and with operant conditioning. The latter worked the best; because the fit/predictions were so shitty i didn't even try brain control with the wiener filter or kalman filter. Here is the output of BMIsql on ~6500 data slices, 18 neurons, 5 taps:

here is the prediction summary... note that target x position is doing rather well (probably because we are training units to respond to this)

output of BMIsql:

order of columns: unit,channel, lag, snr, variable

    2.0000   29.0000         0    1.0872    6.0000
    1.0000   53.0000    3.0000    1.0870    3.0000
    1.0000   53.0000    2.0000    1.0820    3.0000
    1.0000   82.0000    1.0000    1.0801    7.0000
    1.0000   82.0000    5.0000    1.0678    1.0000
    1.0000   82.0000    4.0000    1.0625    1.0000
    1.0000   82.0000    2.0000    1.0563    7.0000
    1.0000   53.0000    1.0000    1.0558    6.0000
    1.0000    8.0000         0    1.0550    8.0000
    1.0000   70.0000    3.0000    1.0549    2.0000
    1.0000   70.0000    2.0000    1.0536    2.0000
    2.0000   82.0000    4.0000    1.0524    1.0000
    2.0000   82.0000    5.0000    1.0516    1.0000
    1.0000   53.0000    4.0000    1.0506    3.0000
    1.0000   70.0000    4.0000    1.0503    2.0000
    2.0000   29.0000    1.0000    1.0497    5.0000
    2.0000   82.0000    3.0000    1.0494    1.0000
    1.0000   82.0000    3.0000    1.0464    7.0000
    1.0000    8.0000    1.0000    1.0454    8.0000
    1.0000   24.0000    1.0000    1.0450    8.0000
    1.0000   24.0000         0    1.0442    8.0000
    1.0000    8.0000    2.0000    1.0415    8.0000
    1.0000   70.0000    5.0000    1.0396    2.0000
    2.0000   82.0000    1.0000    1.0395    7.0000
    1.0000   24.0000    2.0000    1.0392    8.0000
    1.0000   70.0000    1.0000    1.0389    2.0000
    1.0000   81.0000    1.0000    1.0356    8.0000
    1.0000    8.0000    3.0000    1.0355    8.0000
    2.0000   29.0000    2.0000    1.0334    8.0000
    1.0000   81.0000    2.0000    1.0326    8.0000
    1.0000   24.0000    4.0000    1.0318    8.0000
    1.0000    8.0000    4.0000    1.0298    8.0000
    1.0000   24.0000    3.0000    1.0297    8.0000
    1.0000   28.0000    3.0000    1.0293   11.0000
    2.0000   82.0000    2.0000    1.0292    4.0000
    1.0000   28.0000    1.0000    1.0286   11.0000
    1.0000   28.0000    4.0000    1.0262   11.0000
    1.0000   28.0000    2.0000    1.0243   11.0000
    1.0000   28.0000         0    1.0238   11.0000
    2.0000   29.0000    3.0000    1.0221    8.0000
    1.0000   53.0000         0    1.0215    9.0000
    1.0000   81.0000    3.0000    1.0207    8.0000

Operant conditioning worked exceptionally well for the X axis (channel 29, yellow unit 1 - adding both unit's activity together did not work, the monkey would not play). see http://m8ta.com/tim/clem042307_trainX.MPG For a while he tried controlling the cursor position with the joystick, then after a while he realized this was unnecessary and just modulated unit 29.

Initially I tried operant conditioning of channel 82 for the Y axis, but it quickly appeared that he did not care and that it would not work. Hence I switched to channel 71, which was tried on Saturday the 20th. As before, this unit was tonically active while he was asleep, and almost silent while he was paying attention. an attention neuron? possibly. It also showed high firing rate changes when he struggled, suggesting volitional control. He was somewhat able to control it today... see http://m8ta.com/tim/clem042307_trainY.MPG

{104}
hide / / print
ref: Boline-2005.11 tags: electrophysiology motor cortex force isometric Ashe 2005 date: 04-09-2007 22:39 gmt revision:3 [2] [1] [0] [head]

this seems to be the same as {339}, with a different pubmed id & different author list. bug in the system!

PMID-16193273[0] On the relations between single cell activity in the motor cortex and the direction and magnitude of three-dimensional dynamic isometric force* the majority of cells responded to direction

  • few to the magnitude,
  • and ~10% to the direction & magnitude
  • control of static and dynamic motor systems is based on a common control process!
  • 2d task, monkeys, single-unit recording, regression analysis.

____References____

{338}
hide / / print
ref: Ashe-1994.12 tags: Georgoplous motor control M1 S1 SUA electrophysiology 2D date: 04-09-2007 20:27 gmt revision:2 [1] [0] [head]

PMID-7703686[0] Movement parameters and neural activity in motor cortex and area 5

  • 290 cells in the motor cortex and 207 cells in area 5 (S1)
  • median R^2 = 0.581 & 0.530 in motor cortex
  • most prominent representation of target direction; least prominent representation of acceleration. (though statistically significant correlations were observed for all behavioral parameters)

Duke does not have online access to the article :(

____References____

{292}
hide / / print
ref: Schwartz-2004.01 tags: Schwartz BMI prosthetics M1 review 2004 date: 04-05-2007 16:12 gmt revision:1 [0] [head]

PMID-15217341[0] Cortical Neuro Prosthetics

  • closed-loop control improves performance. see [1]
    • adaptive learning tech, when coupled to the adaptability of the cortex, suggests that these devices can function as control signals for motor prostheses.

____References____

{244}
hide / / print
ref: Shapovalova-2006.1 tags: dopamine learning neocortex rats russians D2 date: 03-12-2007 01:58 gmt revision:0 [head]

PMID-17216714 Motor and cognitive functions of the neostriatum during bilateral blocking of its dopamine receptors

  • systemic application of D1 selective blockers reduced learning in rats
    • probably this effect is not neostriatal:
  • local application of the same blocker on the cortex did not markedly affect learning, though it did effect initiation errors
  • D2 antagonist (raclopride) locally applied to the striatum blocked learning.

{190}
hide / / print
ref: Lavin-2005.05 tags: dopamine PFC VTA prefrontal_cortex ventral_tegmentum 2005 date: 02-05-2007 20:37 gmt revision:1 [0] [head]

PMID-15901782[0]Mesocortical Dopamine Neurons Operate in Distinct Temporal Domains Using Multimodal Signaling

  • good paper, decent review of relevant infos in the introduction.
  • they suggest that the mesocortical system transmits fast signals about reward/salience via corelease of glutamate, whereas dopamine provides a more long-term modulator of cortical processing dynamics.
  • the ventral tegmental area provides dopamine to the prefrontal cortex.
  • DA levels in the PFC can increase ~10x above baseline for 10's of minutes.
    • these responses occur to both to unexpectedly rewarding stimuli as well as to aversive stimuli.
  • brief VTA stimulation invokes a short, transient (~200ms) inhibition of PFC in vivo, and this inhibition is typically blocked by DA antagonists. from: PMID-1436485[1]
    • transient inhibition begins ~20ms after VTA stimulation, which is barely enough time for activation of ionotropic receptors, let alone metabotropic DA receptors.
  • MFB stimulation evoked increased DA levels and an elevation in firing of nearby striatal neurons that outlasted the period of stimulation by > 300s.
  • strangely, the excitatory glutamergic response in the PFC to VTA stimulation is blocked by lesion of the MFB.
  • in suppport of co-release, TH-positive neurons in rats and primates are co-reactive for glutamate.
    • DA neurons can form glutamate synapses in vitro.
  • check it out:
    • midbrain DA neurons respond by firing a ~200ms burst of spikes to primary rewards, conditioned, or secondary rewards, rewards that are not predicted, and novel or unexpected stimuli.
    • DA neurons are activated by rewarding events that are better than predicted, remain unaffected by events that are as good as predicted, and are depressed by events that are worse than predicted (yet they do not cite any refs for this... there are a bunch of refs in the prev sentence. ) see:
    • stress can also increase PFC DA

____References____

{176}
hide / / print
ref: Brockwell-2004.04 tags: particle_filter Brockwell BMI 2004 wiener filter population_vector MCMC date: 02-05-2007 18:54 gmt revision:1 [0] [head]

PMID-15010499[0] Recursive Bayesian Decoding of Motor Cortical Signals by Particle Filtering

  • It seems that particle filtering is 3-5 times more efficient / accurate than optimal linear control, and 7-10 times more efficient than the population vector method.
  • synthetic data: inhomogeneous poisson point process, 400 bins of 30ms width = 12 seconds, random walk model.
  • monkey data: 258 neurons recorded in independent experiments in the ventral premotor cortex. monkey performed a 3D center-out task followed by an ellipse tracing task.
  • Bayesian methods work optimally when their models/assumptions hold for the data being analyzed.
  • Bayesian filters in the past were computationally inefficient; particle filtering was developed as a method to address this problem.
  • tested the particle filter in a simulated study and a single-unit monkey recording ellipse-tracing experiment. (data from Rena and Schwartz 2003)
  • there is a lot of math in the latter half of the paper describing their results. The tracings look really good, and I guess this is from the quality of the single-unit recordings.
  • appendix details the 'innovative methodology ;)

____References____

{143}
hide / / print
ref: Marzullo-2006.12 tags: kipke BMI cingulate cortex 2006 date: 02-05-2007 17:14 gmt revision:1 [0] [head]

PMID-17190032[0] http://hardm.ath.cx:88/pdf/Marzullo2006_CingulateCortexBMI.pdf

  • motivation: ALS or PLS (primary lateral sclerosis) can damage upper motor neurons.
  • cingulate cortex has both cognitive and motor properties. & is involved in reward-based motor planning.
  • they give a long list of things that the cingulate cortex has been found to be involved in, including:
    • reward-based motor planning and reward expectancy
    • behavioral inhibition
    • stimulus-reward association
    • trace-conditioning
    • attention in complex discrimination tasks
    • error detection in humans
    • pain perception in human, too.
  • seven rats were able to modulate activity of neurons in cingulate cortex in order to recieve reward.
    • 52-84% percent of cingulate cortex neurons can be trained for a BMI; each seem to be independent.
  • michigan electrode, 16 channels.
  • auditory feedback.
  • food reward.
  • set the threshold based on the mean firing rate of SUA / MUA + a scalar times the stdev of the firing rate. the scalar was varied to allow 30-40% correct or operant rates.
  • used monte carlo simulations to verify the animal was performing above chance.
  • rat cortex is smooth :)
  • some cells increased their firing rate, some decreased (gaussian smoothed mean firing rate)
    • verified cell status with autocorrelogram.
result: cingulate cortex, like probably anywhere else, can come under voluntary control.

____References____

{117}
hide / / print
ref: Gdowski-2001.02 tags: globus pallidus reward electrophysiology 2001 date: 0-0-2007 0:0 revision:0 [head]

PMID-11160530 Context Dependency in the Globus Pallidus Internal Segment During Targeted Arm Movements

  • most of the movement-responsive neurons had modulations in the cued segment of the task, not in the subsequent relaxed, self-paced phase.
  • this constitutes a reward or context-dependence.
{116}

{144}
hide / / print
ref: Blankertz-2006.06 tags: BMI EEG ECoG competiton 2006 date: 0-0-2007 0:0 revision:0 [head]

PMID-16792282 http://hardm.ath.cx:88/pdf/BCIcompetition2006.pdf

{146}
hide / / print
ref: van-2004.11 tags: anterior cingulate cortex error performance monitoring 2004 date: 0-0-2007 0:0 revision:0 [head]

PMID-15518940 Errors without conflict: implications for performance monitoring theories of anterior cingulate cortex.

  • did a event-locked fMRI to study whether the ACC would differentiate between correct and incorrect feedback stimuli in a time estimation task.
  • ACC seems to be not involved in error detection, just conflict.
----
  • according to one theory, ERN is generated as part of a reinforcement learning process. (Holroyd and Coles 2002): behavior is monitored by an 'adaptive critic' in the basal ganglia.
    • in this theory, the ACC is used to select between mental processes competing to access the motor system.
    • ERN corresponds to a decrease in dopamine.
    • ERN occurs when the stimulus indicates that an error has occured.
  • alternately, the ACC can monitor for the presence of conflict between simultaneously active but incompatible sensory/processing streams.
    • the ACC is active in correct trials in tasks that require conflict resolution. + it makes sense from a modeling strategy: high-energy state is equivalent to a state of conflit: many neurons are active at the same time.
    • that is, it is a stimuli resolver: e.g. the stroop task.
  • some studies localize (and the authors here indicate that the source-analysis that localizes dipole sources is inaccurate) the error potential to the posterior cingulate cortex.
    • fMRI solves this problem.
  • from their figures, it seems that the right putamen + bilateral caudate are involved in their time-estimation task (subjects has to press a button 1 second after a stimulus cue; feedback then guided/misguided them toward/away from 1000ms; subjects, of course, adjusted their behavior)
    • no sign of ACC activation was shown - as hard as they could look - despite identical (more or less) experimental design to the ERN studies.
      • hence, ERN is generated by areas other than the ACC.
  • in contrast, the stroop task fully engaged the anterior cingulate cortex.
  • cool: perhaps, then, error feedback negativity is better conceived as an (absence of) superimposed "correct feedback positivity" 'cause no area was more active in error than correct feedback.
  • of course, one is measuring brain activation through blood flow, and the other is measuring EEG signals.

{148}
hide / / print
ref: Vidal-2000.01 tags: EEG ERN error negativity conflict resolution 2000 date: 0-0-2007 0:0 revision:0 [head]

PMID-10686362 Is the 'error negativity' specific to errors?

  • they see a small ERN on correct trials, focused @ FCz.
  • rather than an error-process per se, we propose that the ERN reflects either a comparison process leading secondarily to error detection, or an emotional reaction.

{151}
hide / / print
ref: Flash-2001.12 tags: Flash Sejnowski 2001 computational motor control learning PRR date: 0-0-2007 0:0 revision:0 [head]

PMID-11741014 Computational approaches to motor control. Tamar Flash and Terry Sejnowski.

  • PRR = parietal reach region
  • essential controviersies (to them):
    • the question of motor variables that are coded by neural populations.
    • equilibrium point control vs. inverse dynamics (the latter is obviously better/more correct)

{173}
hide / / print
ref: Wrosch-2007.02 tags: goals health 2007 disengagement date: 0-0-2007 0:0 revision:0 [head]

PMID-17259585 Giving up on unattainable goals: benefits for health?

  • Across the three studies, the findings demonstrate that the ability to disengage from unattainable goals is associated with better self-reported health and more normative patterns of diurnal cortisol secretion.
  • Goal reengagement, by contrast, was unrelated to indicators of physical health
  • PMID-17259584 Does self-affirmation, cognitive processing, or discovery of meaning explain cancer-related health benefits of expressive writing? quote: A content analysis of the essays showed that self-affirmation writing was associated with fewer physical symptoms at a 3-month follow-up assessment

{189}
hide / / print
ref: neuro notes-0 tags: Dopamine receptor D1 D2 date: 0-0-2007 0:0 revision:0 [head]

http://www.cnsforum.com/imagebank/section/receptor_systems_Dopaminergic/default.aspx

  • the D1 receptor is coupled to stimulatory G-proteins, which cause cell depolarization. (pathway: stimulatory g-protein -> actibation of adenylate cyclase converts ATP -> cAMP -> PKC -> phosphorylation of sodium (and calcium?) channel.
  • the D2 receptor (family?) is coupled to inhibitory G-proteins, which decrease the activity of adenylate cyclase. this is a pretty vague picture.

{17}
hide / / print
ref: bookmark-0 tags: debian linux sarge apache2 subversion install ssl date: 0-0-2006 0:0 revision:0 [head]

http://mattl.co.uk/apache2subversiondebianhowto.html pretty good. SSL and subversion seems to cause problems with apache2 on this 'unstable' Debian build - it complains of a BAD MAC header after a deterministic number of bytes are transmitted. Therefore I moved to port 80 from 443.

{72}
hide / / print
ref: abstract-0 tags: tlh24 error signals in the cortex and basal ganglia reinforcement_learning gradient_descent motor_learning date: 0-0-2006 0:0 revision:0 [head]

Title: Error signals in the cortex and basal ganglia.

Abstract: Numerous studies have found correlations between measures of neural activity, from single unit recordings to aggregate measures such as EEG, to motor behavior. Two general themes have emerged from this research: neurons are generally broadly tuned and are often arrayed in spatial maps. It is hypothesized that these are two features of a larger hierarchal structure of spatial and temporal transforms that allow mappings to procure complex behaviors from abstract goals, or similarly, complex sensory information to produce simple percepts. Much theoretical work has proved the suitability of this organization to both generate behavior and extract relevant information from the world. It is generally agreed that most transforms enacted by the cortex and basal ganglia are learned rather than genetically encoded. Therefore, it is the characterization of the learning process that describes the computational nature of the brain; the descriptions of the basis functions themselves are more descriptive of the brain’s environment. Here we hypothesize that learning in the mammalian brain is a stochastic maximization of reward and transform predictability, and a minimization of transform complexity and latency. It is probable that the optimizations employed in learning include both components of gradient descent and competitive elimination, which are two large classes of algorithms explored extensively in the field of machine learning. The former method requires the existence of a vectoral error signal, while the latter is less restrictive, and requires at least a scalar evaluator. We will look for the existence of candidate error or evaluator signals in the cortex and basal ganglia during force-field learning where the motor error is task-relevant and explicitly provided to the subject. By simultaneously recording large populations of neurons from multiple brain areas we can probe the existence of error or evaluator signals by measuring the stochastic relationship and predictive ability of neural activity to the provided error signal. From this data we will also be able to track dependence of neural tuning trajectory on trial-by-trial success; if the cortex operates under minimization principles, then tuning change will have a temporal relationship to reward. The overarching goal of this research is to look for one aspect of motor learning – the error signal – with the hope of using this data to better understand the normal function of the cortex and basal ganglia, and how this normal function is related to the symptoms caused by disease and lesions of the brain.