void update() {
		for(int i = 0; i < pulses.size(); i++) {
			pulses[i].update(people);
		}
		fbo.begin();
		ofPushStyle();
		ofSetLineWidth(30);
		ofSetColor(0, 10);
		ofFill();
		ofRect(0, 0, fbo.getWidth(), fbo.getHeight());
		ofSetColor(255);
		ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2);
		float saturation = ofMap(pulses.size(), 1, 10, 0, 255, true);
		for(int i = 0; i < pulses.size(); i++) {
			ofPushMatrix();
			ofRotate(pulses[i].getAngle());
			ofSetColor(ofColor::fromHsb(pulses[i].getHue(), saturation, 255));
			ofLine(0, 0, ofGetWidth() / 2, 0);
			ofPopMatrix();
		}
		ofPopStyle();
		fbo.end();
		fbo.readToPixels(fboPixels);
		ledRing.update(fboPixels);
		float presence = 0;
		for(int i = 0; i < people.size(); i++) {
			presence += people[i].getPresence();
		}
		presence /= people.size();
		midi.sendControlChange(2, 1, presence);
	}
	void update(vector<Person>& people) {
		float angle = getAngle();
		ofVec2f direction = makeRotatedVector(angle);
		float bestDiff;
		for(int i = 0; i < people.size(); i++) {
			float diff = direction.angle(people[i].position);
			if(i == 0 || abs(diff) < abs(bestDiff)) {
				bestDiff = diff;
			}
		}
		float bounceEpsilon = 15;
		if(abs(bestDiff) < bounceEpsilon &&
			 (bestDiff>0) != (lastDiff>0) &&
			 ((bestDiff < 0 && clockwise) || (bestDiff > 0 && !clockwise))) {
			bounce();
		} else {
			lastDiff = bestDiff;
			lastAngle = angle;
		}
		midi.sendControlChange(1, 1 + 2 * index + 0, ofMap(direction.x, 0, ofGetWidth(), 0, 127, true));
		midi.sendControlChange(1, 1 + 2 * index + 1, ofMap(direction.y, 0, ofGetHeight(), 0, 127, true));
	}
 void ctlOut(int cc, int value, int channel = 0)
 {
     if (channel != 0) mChannel = channel;
     mMidiOut.sendControlChange(mChannel, cc, value);
 }
	void setPosition(float x, float y) {
		position.set(x, y);
		midi.sendControlChange(1, 64 + index, getPresence());
	}