We just finished the install of “Border Tuner” a new artwork by Rafael Lozano-Hemmer. I thought it might be nice to share some of the code and methods I ended up using to solve the installation’s requirements.
18 Syncrolite XL moving head lights needed to be pointed across the MX/US border and had to perform different motion behaviours together. Via a rotary dial participants were able to sweep a group of 3 lights a long an approx. 270˚ motion path.
Thanks to the great work of @elliotwoods and his ofxCeres addon it was relatively simple to convert virtual 3D points in to pan tilt angles and then in to the correct DMX levels needed for each channel.
In the addon I was able to place my virtual lights and place/translate them more or less to match the real world. A surveyor provided use with the UTM data, basically XYZ location data. So we knew exactly where each light was in relation to the others.
The tricky part was to add the correct rotation vector / orientation to the virtual light models. Translation and orientation are bing used by the addon to then calculate the panTilt angles. In my case I pointed all lights to 4 different places in the sky. One was at 0,0,75 meters, which was about the middle of my “stage”. Others points were picked which formed light bridges across the border. We then had multiple people from multiple angles walkie talkie to me if they thought the lights looked aligned and if they thought the lights needed adjustment in pan or tilt.
I adjusted rotationX and rotationZ, which to some extend moved the light beams in to a better position. But these rotation values do not actually translate directly in to pan and tilt. As we know form ofNode and 3D object orientation that by changing one orientation axis the others get effected too. So, the adjustment on those axis value could only be very slight.
Many times, I was switching back and forth between my previously picked places and kept on adjusting the rotationX and rotationZ values. Eventually we found a good mix. But only when the lights stayed in the same tilt angle range as they were calibrated in.
These moving head lights have a pan range of -270 to +270˚ degrees and most of the time a tilt range of -135˚ to +135˚. This means the same point in the sky can be hit with 4 different pan tilt angle combinations. I noticed that I got the best results when I forced the software to only consider positive tilt angles and discard all other panTilt options. Elliot’s code made it very easy to add these limitations.
I have to admit ofxCeres can do so much more and I did not have the time to use it to it’s fullest potential. The add-on actually let’s you calibrate your moving head lights based on previously collected XYZ marker locations. You point each of your lights to those know locations and collect the pan tilt angles. It’s good to point the lights at the same spot using all the possible panTilt pairs.
The result is that the code will place and orient your virtual light correctly.Virtual 3D points will now match your real world points.
The artwork has 3 “stations” on in Parque Chamizal, Ciudad Juárez and 3 is Bowie High School, El Paso. Each station has a microphone and a loud speaker. The voices from each station needed to be available for all other stations. When the lights from station A pointed at station B, the audio from station B needed to be heard at station A. The experience had to be one of tuning a radio dial and slowly fading in and out of different radio stations.
In the past I have used @roymacdonald great ofxSoundObject addon which has a matrix mixer option build in.
I had used his addon extensively in the past to take in multiple microphone streams, audio player files and Dante audio network streams. Those could then be mixed together in dynamic ways and out put to a multiple channel sound device or the Dante Virtual Soundcard.
For this piece Roy extended the addon and created ofxSoundObjects-NDI which allows for connection to the ofxNDI addon made by @nariakiiwatani . NDI usually is used for video+audio. But in our case we only needed audio and did not need highest quality either.
This allowed me to write a NDI sender app that mixed the mic input and an audio file and send them out in to the NDI network. Each of the 6 stations had a macOS 10.14 Mac mini running with this sender app. Also a 6 channel NDI matrix receiver app ran on the same machine, mixing all the incoming NDI streams and outputting them to the loudspeaker.
This worked very successfully and was pretty stable. It took a bit of time to find the right approach to reconnect all the apps in case one got restarted. NDI is pretty good at auto reconnecting but it does not work for all cases. So, in some cases apps had to exit themselves and got restarted by a watchdog script.
I learned that each computer should at least have a 10 mbps connection, which meant that our 100 mbps network was plenty fast.
The communication between the main light controller app and the 6 audio stations was done using ofxOSC since I was more familiar with is. ofxNDI’s metadata option could have been used to also send non-audio messages between the computers. Maybe next time
@Caroline_Record and Guillaume Tremblay, my dear colleagues wrote code to allow the light controller app to post its state to the internet. When ever 2 light stations form a bridge we wanted the website to mimic this state. Caroline used ofxLibwebsockets for this feature. We learned that networks can be tricky. In our case Transtelco, a local network company, was kind enough to provide us with a speedy connection between both countries. They gave us a local and a public network. We still had to insure that ofxLibwebsockets did not block our apps incase the network got lost, or the internet became unreachable. For example pinging needed to be done in a thread and socket setup only be done if internet existed.
If you have a chance to drop by, it’s still on until November 24th.
Border Tuner light controller, showing ofxCeres moving head controls.
Border Tuner light controller, showing 3D visualization of an apex behaviour.
NDI sender, NDI Matrix-Receiver and OBS video recorder.