At last, here comes the ultimate video of MB Led showing off a large panel of its features.
At last, here comes the ultimate video of MB Led showing off a large panel of its features.
During the week end, we welded the MB Leds with Alexis. It was quite long but eventually we have our own blocks.
Benjamin created the remote functionality; It works quite well. If a block turns of 180°, it will be the remote to change the program.
I fixed some problems in the algorithm with the MB Leds and I will continue until the presentation.
After firmware transmission Cédric tried the firmware upgrade already implemented on TP PCB by Benjamin but failed to implement it on MB Led blocks in due time and eventually stopped his work : In fact, we have few time left and we prefer to focus on the presentation. Now, he will work on an animations.
These last two days we mainly worked on tuning the PID coefficients to improve the stability. In this way, we tried to find the best set of PID coefficients so that RoseWheel could raise from an almost horizontal position and recover stability as soon as possible and then maintain this stability over time, even under hard external perturbation. We also worked on improving the coefficients we found for the human driving mode to make the right compromise between smooth-driving and responsiveness.
During this test and improve phase, Alexis advised us to plot the curve of the different values critical for our system. Thus, we plotted over time the value of the angle and the angle rate before and after the kalman filtering and also the command sent to the motor calculated by our PID algorithm.
It made us find 2 problems in our software that explains why at the beginning RoseWheel was so unstable:
As we obtained satisfying results at making RoseWheel maintain its equilibrium, we started working on other features :
We implemented the safety switch and elaborated a protocol to avoid as much dangerous situations as possible :
At the very beginning, when one presses the power on button, RoseWheel is in self-driving-mode by default. That means it will try to reach its equilibrium position as soon as possible and then remain in this position. We assume that the user isn’t too silly and, for instance, will not try to power on RoseWheel in an almost horizontal position whereas he is facing it. Then, as soon as the safety switch that is located on the base is pressed, that means that someone has its foot on RoseWheel and wants to ride it : RoseWheel switches to its human-drive mode. If suddenly the safety switch is released, RoseWheel checks the angle. If it’s almost 0°, that means that RoseWheel’s speed is almost 0 and the person maybe wants to get out, then calmly RoseWheel switches to its self-driven mode (we still need to implement it). If the angle is under 75°, that could means two things: the person has felt down or the person has temporarily raised its foot. Thus, if the safety switch isn’t pressed within 1 second, RoseWheel makes a special noise, then, if it’s still not switched on within another second, RoseWheel switch to its self-driven mode. Finally, if the angle is greater than 75°, that means that the person has felt down and RoseWheel could represent a menace for people around, motors are disabled.
2) Concerning the obstacle detection, we almost finished to implement the sharps and sonar drivers. As these detectors are really sensitive to the external conditions, we still have to test them and see how they react in the different environnements RoseWheel will evolve in.
3) Concerning the remote control, we almost finished to implement the drivers for the Bluetooth, we made some tests yesderday, but we still need to continue them today and we will talk more about it in the next article.
Since our last post, Guillaume is still on the algorithm. Benjamin developed a display task for the old and new GLiPs. Now, we can see directly what’s going on in the network and try to debug it (see the picture). Yesterday, Guillaume tried to resolve bugs of freezing GLiP while the algorithm is running. He had to change many things in order to fix this and the only remaining freeze happens when some blocs leave the network.
There are some troubles when a block isn’t gone but don’t communicate with his neighbors. The biggest problem is when a block is rickety and that he communicates for time to time : he is considered as gone and soon after, he is here, etc. When this happens, the network can fail.
A little video to illustrate the visual debug:
Benjamin is develloping a special snake game concept for our system.
Guillaume and Benjamin.
Today Alexis delivered us the whole set of the train light circuit. Initially we tried to add another light card to our current testing configuration. We managed to get 2 light cards configured , so up to this point the central station has been able to control 2 light cards, the train and an ethernet connection in total.
Currently we are working on stabilizing the NMRAnet CAN bus protocol. We encountered problems of what we think mainly concern, a difference between the CAN bus bandwidth and the processing bandwidth of the central station. For example, as we observed, during programming the events of a node, within an environment of multiple CAN packets exhange, the central station missed acknowledgement frames sent by the node after the configuration file. This prevented the central station from successfully programming a node. After inserting a delay between sending the data of the configuration file and the ACK we observed that the node got successfully programmed. This led us to assume a mismatch in processing and CAN bus bandwidth.
In order to face these kind of problems which have appeared, we will adjust the CAN bus bandwidth, use one buffer for event processing and another one for network-management purposes, and additionally install event filters on the fly accordingly for each node.
It is time to make a debriefing about last week achievement.
Colour gradient and intensity
Benjamin worked on the Led driver in order to display a picture and has fixed some problems with luminosity. He balanced green, blue and red and we are now able to display a white colour on our blocks (although a blue tint remains on videos). From now on, we also have a linear gradient of intensity for each primary colour. In order to obtain this gradient, we first tried to put a linear variation of intensity in registers, but it appeared linearity didn’t worked and he had to adjusted individually each step.
Electronic visual display:
An interruption is raised with a frequency of 10kHz and each time a new line is displayed. As our Led matrix has 8 lines, we have a electronic visual display at 1,25kHz. Each time we want to display a new line we connect to the Led driver through SPI sending it thanks to a vector of 288bits matching a 8 pixel line with three colour and 12 bit of gray control. Actually we only use 4 bit for each colour.
Yesterday I implemented acknowledgement system with IrDA transmission. First I needed to divide our sending queue into 2 queues: one for quick packets which don’t need ack such as PING, PONG and synchronizing messages sent at high frequency and allowing some losses; the other one is for important packet needing a safe transmission. These packet are sent to a task which could be seen as a buffer sending a packet (every 40ms) until it receives an ACK and then picking up the next one. In order to identify a packet an ACK transmit the ID of the sender and the ID of the packet it acknowledge and when an ACK packet is received, a message containing these information is send to the task managing output packets. In order to avoid loop waiting for an ACK , we use a counter and if a packet is not acknowledged after 10 tries we consider it as a lost packet (for ping messages, if we don’t receive one PONG for 10 of our PING, we consider the neighbour as gone). Once a neighbour is gone we empty the sending queues for this UART.
This system is not optimal, being slow, but at higher speed we got a lot corruption during transmission and more packet are lost.
We decided to rethink our algorithm after the reactions of yesterday’s post. We changed the algorithm when some block is leaving the network. If someone is missing, the block which notice that says it to the network. Every other block answer by « I’m still here ». If the leader doesn’t answer (probably he’s gone), there is an other election; those who don’t answer are considered to be out of the network. In this algorithm, the blocks keep in memory their position and orientation and we don’t have to start an election every time some block quits.
NOTE: Now once a direction is decided, it is kept when the connection is lost.
Today we were able to control our leds using the TLC5945 Led Driver, although we have not yet exploited it’s capabilities at full extent. As Alexis and Samuel proposed during our meeting, we should use dot correction in order to balance the mismatch of luminosity between green, red and orange. In addition, it would be useful to control intensity through TLC5945 grayscale mode especially once we assemble the whole system containing 60 leds.
Our next PSSC concerns DCC control of the train , although there are many more things we are concerned about. At this point we are mostly concerned about switching from our laboratory based STM32F103 cards, to the STM32F107 based central station card. For the moment we haven’t yet achieved to configure the STM32F107 CAN bus drivers correctly. Once this is done we will do more tests and continue working on the stability of the NMRAnet CAN bus module.
One problem of the NMRAnet CAN bus net module is the fact that in presence of multiple producer consumer events, the nodes fail to reply in time, to the STATUS REQUEST message addressed to them by the central station at some point. We have thought that a possible fact that causes this situation is that for the moment nodes are using only one of the STM32F103′s available CAN bus reception FIFO’s. In this case, processing the status request incoming packets is being delayed by event packets already present in the FIFO . Therefore we think that filtering out NMRAnet producer/ consumer event packets from one of the FIFO’s and letting them pass thorugh the other one seems like an improvement.
As Samuel noticed that there is not formal description of the algorithm, I will do this now.
First of all, all the messages use the packet structure giving by Cédric here. So, they all have an ID and we know who is the sender. I will start by showing all the messages and then I’ll explain the algorithm.
List of the differents messages
There are a large number of messages and they all have specifics arguments.
For the algorithm, I use « interfaces » which are aliases of UARTs. The UARTs are used by the IrDA while the interfaces are used for the algorithm. For example, interface 0 represents the north (and is in reality UART 2), interface 1 is the east (but in reality it’s UART 5), etc.
All the blocks know :
They have a network table (for each ID, they know the position (i,j) and who was the leader when they had the information) and an election table (for each ID, they know his state in the election) . We will try to replace theses tables by a list in the future.
Every message except PING and PONG is answered by an ACK message. The PONG message contains the PING ID so it is itself a ACK. If there is no ACK, the message is resend.
When starting all of this, the block starts the timer 5 of the STM32 for the synchronization. (see section 4)
Each block sends PING messages in the 4 directions and start a timer for each direction.
If this interface wasn’t ready before, the block has to check if he knew the neighbor (in order to notice a turn of the other block) or not (in order to start an election.)
Explanation of this check :
When receiving a PONG message from a « new neighbor », the block checks if the « new neighbor » was a neighbor before or not. This is checked by comparing the current interface table and the saved interface table.
To compare the interfaces, the block waits a little bit for PONG message from all the interfaces.
3. The election
When it’s the first PONG from a new neighbor, an election takes place.
In the election, the blocks send messages for their « network » (all the blocks with the same leader). Here, the « network » can be a network of one block (so the leader ID is his ID).
The winner of the election is the network with the larger number of blocks in his network. If this isn’t enough to decide , the lower leader ID is declared winner.
When receiving a CANDIDATE message, the block checks if the candidate can win or not. If he can’t, the block broadcasts a REJECTED message. If he cans, the block broadcasts the CANDIDATE message.
When receiving a REJECTED message with his leader ID, the block stops the timer : he can no longer win the election.
At the end of the timer, one network is the winner. It sends the ELECTED message and everyone broadcasts it.
4. After the election
After the election,the leader is in (0,0). If he was part of a network, he sends his information to the others by sending NETWORK messages.
Then he sends the POSITION message : [YOUR_POSITION leaderID, myOrientation, yourI, yourJ, myInterface]. The block which receive this calculate his new orientation (with « myOrientation », « myInterface ») and change his position in his network table. Then it calculate the position of his neighbors and sends the message.
The leader sends TIME messages (which are broadcasted if they are « young » enough.. That explains the synchroID) from times to times. In his TIME message, there is his current time (according to the STM32). The block that receive this message update his new « current time » (with a function which take into account the emission time) and then sends his current time to others, etc.
5. If someone leaves
If some block leaves the network, there is no PONG message to the PING message of his former neighbor. The former neighbor notices that and broadcasts a RESET_NETWORK message.
The turn mechanism isn’t implemented yet and the ACK mechanism has to be implemented very soon.
Then, there will be messages for the applications (games, firmware upgrade, …).
Algorithm on GLiP block:
Today Guillaume has worked with 9 GLiP blocks, trying our algorithm in order to elect the leader among the network and give positions to each block. He succeed in this when the network is slowly increasing but when all the blocks come in a random way, it is still difficult to have a consistent network. There is still no acknowledge with the IrDA and when some packet is corrupted, the algorithm fails. We have to fix this soon.
Cédric has resolved his problem with UART4&5 for emitting packet. After some tests with Alexis, he found a good value for the resistance(4.7KOhms) to control emission power so that the blocks would communicate only to the neighbors. All potentiometers will be replaced by classical resistances.
Now I can drive the LED matrix using the new driver TLC5951. I can display a 8×8 pixel on the matrix but I have to fix some problems of intensity. We knew that blue is more powerful than red and green and we try to avoid this problem. For the moment, we can’t obtain a perfect white but I’m in a good way to fix this problem.
We had some hardware problems with our Led Driver today, but finally (thanks Alexi) we could test our programs for SPI and initialization of our Led Driver. Now we can control lights from the Led Driver. We are mapping light commands(from the Led Driver) to corresponding CAN messages.
We have progressed on the work on the CAN bootloader. We have been able to send data from the PC to the final card passing through a dummy card which transforms UART messages to CAN messages.
We have been able to simulate the sensors card on our TP card. Now we are able to send an event (pressing the botton) to central card.