가속도 센서를 이용한 공 굴리기 프로그램.
Embeded :
2009. 3. 24. 19:50
반응형
다음은 Cortex-M3 보드에 들어가는 펌웨어임.
가속도 센서의 값을 받아와서 공 굴리기 프로그램에 쓰고
데이터를 UART를 통해 PC로 전송한다.
가속도 센서의 값을 받아와서 공 굴리기 프로그램에 쓰고
데이터를 UART를 통해 PC로 전송한다.
타겟보드 펌웨어 소스코드 보기
- //*****************************************************************************
- //
- // TiltingBoard.c - Bouncing ball LCD example.
- //
- // Copyright (c) 2008 Luminary Micro, Inc. All rights reserved.
- //
- // Software License Agreement
- //
- // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
- // exclusively on LMI's microcontroller products.
- //
- // The software is owned by LMI and/or its suppliers, and is protected under
- // applicable copyright laws. All rights are reserved. You may not combine
- // this software with "viral" open-source software in order to form a larger
- // program. Any use in violation of the foregoing restrictions may subject
- // the user to criminal sanctions under applicable laws, as well as to civil
- // liability for the breach of the terms and conditions of this license.
- //
- // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
- // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
- // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
- // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
- // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
- //
- // This is part of revision 2752 of the Stellaris Peripheral Driver Library.
- //
- //*****************************************************************************
- #include "hw_types.h"
- #include "sysctl.h"
- #include "ssi.h"
- #include "timer.h"
- #include "interrupt.h"
- #include "grlib.h"
- #include "PH240320T_031_LY1Q_HX8347.h"
- #include "myAccel3LV02_hal.h"
- #include "wall.c" //ho
- #include "ball.c" //ho
- //*********for UART********************************************************************
- #include "stdio.h"//ho
- #include "ustdlib.h"//ho
- #include "string.h"//ho
- #include "../../../hw_ints.h"
- #include "../../../hw_ints.h"
- #include "../../../hw_memmap.h"
- #include "../../../hw_types.h"
- #include "../../../src/debug.h"
- #include "../../../src/gpio.h"
- #include "../../../src/interrupt.h"
- #include "../../../src/sysctl.h"
- #include "../../../src/uart.h"
- #include "../rit128x96x4.h"
- //**************************************************************************
- #ifdef DEBUG
- void
- __error__(char *pcFilename, unsigned long ulLine)
- {
- }
- #endif
- #define BORDER_THICK 16
- #define BALL_RADIUS 15
- #define DISPLAY_FREQ 30
- #define ACC_GAIN 5
- #define MAX_ACC 3
- #define MAX_SPEED 15
- #define REBOUNCE_COEF -0.92
- #define FRICTION_COEF 0.98
- static void DrawBorder(tContext * pContext); //ho
- static void TimerIntHandler(void);
- static void DrawBall(tContext * pContext);
- static void CalculateBallPos(tContext * pContext);
- static short g_data_short_array[3];
- static tBoolean g_bNewDataAvailable;
- static short ball_x, ball_y;
- static short ball_x_prev, ball_y_prev;
- static long ball_dx, ball_dy;
- tContext sContext; //ho
- static tBoolean Once;
- static char buff[20];
- static char cur_pos[20];
- //*****************************************************************************
- //
- // The UART interrupt handler.
- //
- //*****************************************************************************
- void
- UARTIntHandler(void)
- {
- unsigned long ulStatus;
- unsigned short i;
- //
- // Get the interrrupt status.
- //
- ulStatus = UARTIntStatus(UART0_BASE, true);
- //
- // Clear the asserted interrupts.
- //
- UARTIntClear(UART0_BASE, ulStatus);
- //
- // Loop while there are characters in the receive FIFO.
- //
- memset(cur_pos,0x00,sizeof(cur_pos));
- i=0;
- while(UARTCharsAvail(UART0_BASE))
- {
- //
- // Read the next character from the UART and write it back to the UART.
- //
- //UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
- //메모리에 다가 UART에서 받은 값을 넣어놨으니까 이걸 알아서 잘 써먹으면 될것 같다.
- memcpy(cur_pos+i,(unsigned char *)UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
- i++;
- }
- }
- //*****************************************************************************
- //
- // Send a string to the UART.
- //
- //*****************************************************************************
- void
- UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
- {
- //
- // Loop while there are more characters to send.
- //
- while(ulCount--)
- {
- //
- // Write the next character to the UART.
- //
- UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
- }
- }
- int main(void)
- {
- //tContext sContext; //ho
- //
- // Set the clocking to use PLL
- //
- SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
- SYSCTL_XTAL_8MHZ);
- //************For UART*******************************************
- // Enable the peripherals used by this example.
- SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
- SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
- // Enable processor interrupts.
- // IntMasterEnable();
- // Set GPIO A0 and A1 as UART pins.
- GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
- // Configure the UART for 115,200, 8-N-1 operation.
- UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 38400,
- (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
- UART_CONFIG_PAR_NONE));
- // Enable the UART interrupt.
- IntEnable(INT_UART0);
- UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
- //************For UART*******************************************
- //
- // Initialize the display driver.
- //
- hx8347Init();
- //
- // Turn on the backlight.
- //
- hx8347BacklightOn();
- //
- // Initialize the graphics context.
- //
- GrContextInit(&sContext, &g_shx8347);
- /*
- * Initialize accelerometer
- */
- MA3_INIT();
- MA3_SetDecimationFactor(0);
- /*
- * Initialize timer
- */
- SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
- TimerConfigure( TIMER0_BASE, TIMER_CFG_32_BIT_PER );
- TimerLoadSet( TIMER0_BASE, TIMER_A, SysCtlClockGet() / DISPLAY_FREQ );
- TimerIntRegister( TIMER0_BASE, TIMER_A, TimerIntHandler );
- //TimerIntEnable( TIMER0_BASE, TIMER_A );
- TimerIntEnable( TIMER0_BASE, TIMER_TIMA_TIMEOUT );
- TimerEnable( TIMER0_BASE, TIMER_A );
- g_bNewDataAvailable = false;
- Once=true;
- ball_x = ball_x_prev = GrContextDpyWidthGet(&sContext) / 2 - 1;
- ball_y = ball_y_prev = GrContextDpyHeightGet(&sContext) / 2 - 1;
- ball_dx = ball_dy = 0;
- //
- // Loop forever.
- //
- while(1)
- {
- if (Once)
- {
- DrawBorder(&sContext); //ho
- Once=false;
- }
- if (g_bNewDataAvailable)
- {
- //CalculateBallPos(&sContext); //ho
- //DrawBall(&sContext); //ho
- g_bNewDataAvailable = false;
- }
- }
- }
- static void CalculateBallPos(tContext * pContext)
- {
- long acc;
- acc = g_data_short_array[0] / ACC_GAIN;
- if (acc > MAX_ACC)
- acc = MAX_ACC;
- if (acc < -1 * MAX_ACC)
- acc = -1 * MAX_ACC;
- ball_dx = FRICTION_COEF * ball_dx + acc;
- /*
- acc = g_data_short_array[1] / ACC_GAIN;
- if (acc > MAX_ACC)
- acc = MAX_ACC;
- if (acc < -1 * MAX_ACC)
- acc = -1 * MAX_ACC;
- ball_dy = FRICTION_COEF * ball_dy - acc;
- */
- if (ball_dx >= MAX_SPEED)
- ball_dx = MAX_SPEED;
- if (ball_dx <= -1 * MAX_SPEED)
- ball_dx = -1 * MAX_SPEED;
- /*
- if (ball_dy >= MAX_SPEED)
- ball_dy = MAX_SPEED;
- if (ball_dy <= -1 * MAX_SPEED)
- ball_dy = -1 * MAX_SPEED;
- */
- ball_x = ball_x + ball_dx;
- // ball_y = ball_y + ball_dy;
- if (ball_x < BORDER_THICK + BALL_RADIUS)
- {
- ball_x = BORDER_THICK + BALL_RADIUS;
- ball_dx = REBOUNCE_COEF * ball_dx;
- }
- /*
- if (ball_y < BORDER_THICK + BALL_RADIUS)
- {
- ball_y = BORDER_THICK + BALL_RADIUS;
- ball_dy = REBOUNCE_COEF * ball_dy;
- }
- */
- if (ball_x > GrContextDpyWidthGet(pContext) - BORDER_THICK - BALL_RADIUS - 1)
- {
- ball_x = GrContextDpyWidthGet(pContext) - BORDER_THICK - BALL_RADIUS - 1;
- ball_dx = REBOUNCE_COEF * ball_dx;
- }
- /*
- if (ball_y > GrContextDpyHeightGet(pContext) - BORDER_THICK - BALL_RADIUS - 1)
- {
- ball_y = GrContextDpyHeightGet(pContext) - BORDER_THICK - BALL_RADIUS - 1;
- ball_dy = REBOUNCE_COEF * ball_dy;
- }
- */
- }
- static void DrawBall(tContext * pContext)
- {
- tRectangle sRect;
- sRect.sXMin = ball_x_prev - BALL_RADIUS;
- sRect.sYMin = ball_y_prev - BALL_RADIUS;
- sRect.sXMax = ball_x_prev + BALL_RADIUS;
- sRect.sYMax = ball_y_prev + BALL_RADIUS;
- GrContextForegroundSet(pContext, ClrWhite);
- GrRectFill(pContext, &sRect);
- GrImageDraw(pContext, ball, ball_x-14, ball_y-14); //ho
- /*
- GrContextForegroundSet(pContext, ClrRed);
- GrCircleFill(pContext, ball_x, ball_y, BALL_RADIUS);
- */ //ho
- ball_x_prev = ball_x;
- ball_y_prev = ball_y;
- }
- static void TimerIntHandler(void)
- {
- TimerIntClear( TIMER0_BASE, TIMER_TIMA_TIMEOUT );
- MA3_CS_ON();
- MA3_READ(MA3_REG_OUTX_L, (unsigned char*)g_data_short_array, sizeof(g_data_short_array));
- MA3_CS_OFF();
- g_bNewDataAvailable = true;
- CalculateBallPos(&sContext); //ho
- DrawBall(&sContext); //ho
- memset(buff,0x00,sizeof(buff));
- //usprintf(buff,"y%dz\n",(long)(g_data_short_array[0] / ACC_GAIN));
- usprintf(buff,"y%dz\n",ball_x);
- UARTSend((unsigned char *)buff, sizeof(buff)); //ho
- Once=false;
- }
- static void DrawBorder(tContext * pContext)
- {
- /*
- tRectangle sRect;
- sRect.sXMin = 0;
- sRect.sYMin = 0;
- sRect.sXMax = GrContextDpyWidthGet(pContext) - 1;
- sRect.sYMax = GrContextDpyHeightGet(pContext) - 1;
- GrContextForegroundSet(pContext, ClrBlue);
- GrRectFill(pContext, &sRect);
- sRect.sXMin = BORDER_THICK;
- sRect.sYMin = BORDER_THICK;
- sRect.sXMax = GrContextDpyWidthGet(pContext) - BORDER_THICK - 1;
- sRect.sYMax = GrContextDpyHeightGet(pContext) - BORDER_THICK - 1;
- GrContextForegroundSet(pContext, ClrWhite);
- GrRectFill(pContext, &sRect);
- */
- GrImageDraw(&sContext, wall, 0, 0); //ho
- //
- // Flush any cached drawing operations.
- //
- GrFlush(pContext);
- }
다음은 Python 과 Panda3d를 이용해서 PC에서 같은 프로그램을 구현한 것임.
보드와 UART 통신을 해서 연동함.
보드와 UART 통신을 해서 연동함.
어플리케이션 소스코드 보기
- # Author: Shao Zhang, Phil Saltzman
- # Last Updated: 5/2/2005
- #
- # This tutorial shows how to detect and respond to collisions. It uses solids
- # create in code and the egg files, how to set up collision masks, a traverser,
- # and a handler, how to detect collisions, and how to dispatch function based
- # on the collisions. All of this is put together to simulate a labyrinth-style
- # game
- import serial #ho
- import threading #ho
- import direct.directbase.DirectStart
- from pandac.PandaModules import CollisionTraverser,CollisionNode
- from pandac.PandaModules import CollisionHandlerQueue,CollisionRay
- from pandac.PandaModules import Material,LRotationf,NodePath
- from pandac.PandaModules import AmbientLight,DirectionalLight
- from pandac.PandaModules import LightAttrib,TextNode
- from pandac.PandaModules import Vec3,Vec4,BitMask32
- from direct.gui.OnscreenText import OnscreenText
- from direct.showbase.DirectObject import DirectObject
- from direct.interval.MetaInterval import Sequence,Parallel
- from direct.interval.LerpInterval import LerpFunc
- from direct.interval.FunctionInterval import Func,Wait
- from direct.task.Task import Task
- import sys
- #Some constants for the program
- #ACCEL = 100 #Acceleration in ft/sec/sec
- #MAX_SPEED = 20 #Max speed in ft/sec
- ACCEL = 70 #Acceleration in ft/sec/sec
- MAX_SPEED = 5 #Max speed in ft/sec
- MAX_SPEED_SQ = MAX_SPEED ** 2 #Squared to make it easier to use lengthSquared
- #Instead of length
- UP = Vec3(0,0,1) #We need this vector a lot, so its better to just have one
- #instead of creating a new one every time we need it
- class World(DirectObject):
- def __init__(self):
- self.com8=serial.Serial(7,38400)
- self.com8
- self.a=''
- self.ret=0
- th=threading.Thread(target=self.get_accel,args=(self,)) #ho
- th.start() #ho
- #This code puts the standard title and instruction text on screen
- self.title = OnscreenText(text="Tilt Detection",
- style=1, fg=(1,1,1,1),
- pos=(0.8,-0.95), scale = .07)
- self.instructions = OnscreenText(text="lm3s8962 board tilts the board",
- pos = (-1.3, .95), fg=(1,1,1,1),
- align = TextNode.ALeft, scale = .05)
- self.accept("escape", sys.exit) #Escape quits
- base.disableMouse() #Disable mouse-based camera control
- camera.setPosHpr(0, -1, 25, 0, -90, 0) #Place the camera
- #Load the maze and place it in the scene
- self.maze = loader.loadModel("models/rrr")
- self.maze.reparentTo(render)
- #Most times, you want collisions to be tested against invisible geometry
- #rather than every polygon. This is because testing against every polygon
- #in the scene is usually too slow. You can have simplified or approximate
- #geometry for the solids and still get good results.
- #
- #Sometimes you'll want to create and position your own collision solids in
- #code, but it's often easier to have them built automatically. This can be
- #done by adding special tags into an egg file. Check maze.egg and ball.egg
- #and look for lines starting with <Collide>. The part is brackets tells
- #Panda exactly what to do. Polyset means to use the polygons in that group
- #as solids, while Sphere tells panda to make a collision sphere around them
- #Keep means to keep the polygons in the group as visable geometry (good
- #for the ball, not for the triggers), and descend means to make sure that
- #the settings are applied to any subgroups.
- #
- #Once we have the collision tags in the models, we can get to them using
- #NodePath's find command
- #Find the collision node named wall_collide
- self.walls = self.maze.find("**/wall_collide")
- #Collision objects are sorted using BitMasks. BitMasks are ordinary numbers
- #with extra methods for working with them as binary bits. Every collision
- #solid has both a from mask and an into mask. Before Panda tests two
- #objects, it checks to make sure that the from and into collision masks
- #have at least one bit in common. That way things that shouldn't interact
- #won't. Normal model nodes have collision masks as well. By default they
- #are set to bit 20. If you want to collide against actual visable polygons,
- #set a from collide mask to include bit 20
- #
- #For this example, we will make everything we want the ball to collide with
- #include bit 0
- self.walls.node().setIntoCollideMask(BitMask32.bit(0))
- #CollisionNodes are usually invisible but can be shown. Uncomment the next
- #line to see the collision walls
- #self.walls.show()
- #We will now find the triggers for the holes and set their masks to 0 as
- #well. We also set their names to make them easier to identify during
- #collisions
- """
- self.loseTriggers = []
- for i in range(2):
- trigger = self.maze.find("**/hole_collide" + str(i))
- trigger.node().setIntoCollideMask(BitMask32.bit(0))
- trigger.node().setName("loseTrigger")
- self.loseTriggers.append(trigger)
- #Uncomment this line to see the triggers
- #trigger.show()
- """
- #Ground_collide is a single polygon on the same plane as the ground in the
- #maze. We will use a ray to collide with it so that we will know exactly
- #what height to put the ball at every frame. Since this is not something
- #that we want the ball itself to collide with, it has a different
- #bitmask.
- self.mazeGround = self.maze.find("**/ground_collide")
- self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))
- self.mazeGround.show()
- #Load the ball and attach it to the scene
- #It is on a root dummy node so that we can rotate the ball itself without
- #rotating the ray that will be attached to it
- self.ballRoot = render.attachNewNode("ballRoot")
- self.ball = loader.loadModel("models/ball")
- self.ball.reparentTo(self.ballRoot)
- #Find the collison sphere for the ball which was created in the egg file
- #Notice that it has a from collision mask of bit 0, and an into collison
- #mask of no bits. This means that the ball can only cause collisions, not
- #be collided into
- self.ballSphere = self.ball.find("**/ball")
- self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
- self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())
- #No we create a ray to start above the ball and cast down. This is to
- #Determine the height the ball should be at and the angle the floor is
- #tilting. We could have used the sphere around the ball itself, but it
- #would not be as reliable
- self.ballGroundRay = CollisionRay() #Create the ray
- self.ballGroundRay.setOrigin(0,0,5) #Set its origin
- self.ballGroundRay.setDirection(0,0,-1) #And its direction
- #Collision solids go in CollisionNode
- self.ballGroundCol = CollisionNode('groundRay') #Create and name the node
- self.ballGroundCol.addSolid(self.ballGroundRay) #Add the ray
- self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) #Set its bitmasks
- self.ballGroundCol.setIntoCollideMask(BitMask32.allOff())
- #Attach the node to the ballRoot so that the ray is relative to the ball
- #(it will always be 5 feet over the ball and point down)
- self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol)
- #Uncomment this line to see the ray
- self.ballGroundColNp.show()
- #Finally, we create a CollisionTraverser. CollisionTraversers are what
- #do the job of calculating collisions
- self.cTrav = CollisionTraverser()
- #Collision traverservs tell collision handlers about collisions, and then
- #the handler decides what to do with the information. We are using a
- #CollisionHandlerQueue, which simply creates a list of all of the
- #collisions in a given pass. There are more sophisticated handlers like
- #one that sends events and another that tries to keep collided objects
- #apart, but the results are often better with a simple queue
- self.cHandler = CollisionHandlerQueue()
- #Now we add the collision nodes that can create a collision to the
- #traverser. The traverser will compare these to all others nodes in the
- #scene. There is a limit of 32 CollisionNodes per traverser
- #We add the collider, and the handler to use as a pair
- self.cTrav.addCollider(self.ballSphere, self.cHandler)
- self.cTrav.addCollider(self.ballGroundColNp, self.cHandler)
- self.cTrav.setRespectPrevTransform(True) #added by ho
- #Collision traversers have a built in tool to help visualize collisions.
- #Uncomment the next line to see it.
- self.cTrav.showCollisions(render)
- #This section deals with lighting for the ball. Only the ball was lit
- #because the maze has static lighting pregenerated by the modeler
- lAttrib = LightAttrib.makeAllOff()
- ambientLight = AmbientLight( "ambientLight" )
- ambientLight.setColor( Vec4(.55, .55, .55, 1) )
- lAttrib = lAttrib.addLight( ambientLight )
- directionalLight = DirectionalLight( "directionalLight" )
- directionalLight.setDirection( Vec3( 0, 0, -1 ) )
- directionalLight.setColor( Vec4( 0.375, 0.375, 0.375, 1 ) )
- directionalLight.setSpecularColor(Vec4(1,1,1,1))
- lAttrib = lAttrib.addLight( directionalLight )
- self.ballRoot.node().setAttrib( lAttrib )
- #This section deals with adding a specular highlight to the ball to make
- #it look shiny
- m = Material()
- m.setSpecular(Vec4(1,1,1,1))
- m.setShininess(96)
- self.ball.setMaterial(m, 1)
- #Finally, we call start for more initialization
- self.start()
- def start(self):
- #The maze model also has a locator in it for where to start the ball
- #To access it we use the find command
- startPos = self.maze.find("**/start").getPos()
- self.ballRoot.setPos(startPos) #Set the ball in the starting position
- self.ballV = Vec3(0,0,0) #Initial velocity is 0
- self.accelV = Vec3(0,0,0) #Initial acceleration is 0
- #For a traverser to actually do collisions, you need to call
- #traverser.traverse() on a part of the scene. Fortunatly, base has a
- #task that does this for the entire scene once a frame. This sets up our
- #traverser as the one to be called automatically
- base.cTrav = self.cTrav
- #Create the movement task, but first make sure it is not already running
- taskMgr.remove("rollTask")
- self.mainLoop = taskMgr.add(self.rollTask, "rollTask")
- self.mainLoop.last = 0
- #This function handles the collision between the ray and the ground
- #Information about the interaction is passed in colEntry
- def groundCollideHandler(self, colEntry):
- #Set the ball to the appropriate Z value for it to be exactly on the ground
- newZ = colEntry.getSurfacePoint(render).getZ()
- self.ballRoot.setZ(newZ+.4)
- #Find the acceleration direction. First the surface normal is crossed with
- #the up vector to get a vector perpendicular to the slope
- norm = colEntry.getSurfaceNormal(render)
- accelSide = norm.cross(UP)
- #Then that vector is crossed with the surface normal to get a vector that
- #points down the slope. By getting the acceleration in 3D like this rather
- #than in 2D, we reduce the amount of error per-frame, reducing jitter
- self.accelV = norm.cross(accelSide)
- #This function handles the collision between the ball and a wall
- def wallCollideHandler(self, colEntry):
- #First we calculate some numbers we need to do a reflection
- norm = colEntry.getSurfaceNormal(render) * -1 #The normal of the wall
- curSpeed = self.ballV.length() #The current speed
- inVec = self.ballV / curSpeed #The direction of travel
- velAngle = norm.dot(inVec) #Angle of incidance
- hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
- hitDir.normalize()
- hitAngle = norm.dot(hitDir) #The angle between the ball and the normal
- #Ignore the collision if the ball is either moving away from the wall
- #already (so that we don't accidentally send it back into the wall)
- #and ignore it if the collision isn't dead-on (to avoid getting caught on
- #corners)
- if velAngle > 0 and hitAngle > .995:
- #Standard reflection equation
- reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec
- #This makes the velocity half of what it was if the hit was dead-on
- #and nearly exactly what it was if this is a glancing blow
- self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))
- self.ballV = reflectVec *0 #This line make reflection velocity to zero. by ho
- #Since we have a collision, the ball is already a little bit buried in
- #the wall. This calculates a vector needed to move it so that it is
- #exactly touching the wall
- disp = (colEntry.getSurfacePoint(render) -
- colEntry.getInteriorPoint(render))
- newPos = self.ballRoot.getPos() + disp
- self.ballRoot.setPos(newPos)
- #This is the task that deals with making everything interactive
- def rollTask(self, task):
- #Standard technique for finding the amount of time since the last frame
- dt = task.time - task.last
- task.last = task.time
- #If dt is large, then there has been a #hiccup that could cause the ball
- #to leave the field if this functions runs, so ignore the frame
- if dt > .2: return Task.cont
- #The collision handler collects the collisions. We dispatch which function
- #to handle the collision based on the name of what was collided into
- for i in range(self.cHandler.getNumEntries()):
- entry = self.cHandler.getEntry(i)
- name = entry.getIntoNode().getName()
- if name == "wall_collide": self.wallCollideHandler(entry)
- elif name == "ground_collide": self.groundCollideHandler(entry)
- #elif name == "loseTrigger": self.loseGame(entry)
- #Read the mouse position and tilt the maze accordingly
- """
- if base.mouseWatcherNode.hasMouse():
- mpos = base.mouseWatcherNode.getMouse() #get the mouse position
- #self.maze.setP(mpos.getY() * -10)
- self.maze.setR(mpos.getX() * 10)
- print str(mpos.getX() * 10)
- """
- if 1:
- self.maze.setR(self.ret / 21) #ho commended by ho
- #print str(self.ret / 21)
- #Finally, we move the ball
- #Update the velocity based on acceleration
- self.ballV += self.accelV * dt * ACCEL
- #Clamp the velocity to the maximum speed
- if self.ballV.lengthSquared() > MAX_SPEED_SQ:
- self.ballV.normalize()
- self.ballV *= MAX_SPEED
- #Update the position based on the velocity
- self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV * dt))
- #print int(self.ballRoot.getPos().getX()+6) #Send UART ball's POS
- self.com8.write( str(int(self.ballRoot.getPos().getX()+6))+'\r' )
- #This block of code rotates the ball. It uses something called a quaternion
- #to rotate the ball around an arbitrary axis. That axis perpendicular to
- #the balls rotation, and the amount has to do with the size of the ball
- #This is multiplied on the previous rotation to incrimentally turn it.
- prevRot = LRotationf(self.ball.getQuat())
- axis = UP.cross(self.ballV)
- newRot = LRotationf(axis, 45.5 * dt * self.ballV.length())
- self.ball.setQuat(prevRot * newRot)
- return Task.cont #Continue the task indefinitely
- #If the ball hits a hole trigger, then it should fall in the hole.
- #This is faked rather than dealing with the actual physics of it.
- """
- def loseGame(self, entry):
- #The triggers are set up so that the center of the ball should move to the
- #collision point to be in the hole
- toPos = entry.getInteriorPoint(render)
- taskMgr.remove('rollTask') #Stop the maze task
- #Move the ball into the hole over a short sequence of time. Then wait a
- #second and call start to reset the game
- Sequence(
- Parallel(
- LerpFunc(self.ballRoot.setX, fromData = self.ballRoot.getX(),
- toData = toPos.getX(), duration = .1),
- LerpFunc(self.ballRoot.setY, fromData = self.ballRoot.getY(),
- toData = toPos.getY(), duration = .1),
- LerpFunc(self.ballRoot.setZ, fromData = self.ballRoot.getZ(),
- toData = self.ballRoot.getZ() - .9, duration = .2)),
- Wait(1),
- Func(self.start)).start()
- """
- def get_accel(self, id): #ho
- while(1):
- temp=self.com8.read()
- if(temp=='y'):
- self.a=''
- elif(temp=='z'):
- self.ret = int(self.a)
- else:
- self.a+=temp
- #Finally, create an instance of our class and start 3d rendering
- w = World()
- run()
빠른 통신이 필요 없을것 같아서 보드와의 Baudrate를 2400으로 맞췄는데 이렇게 해놓으니까 보드가 마우스를 먹는 현상이 발생하였다.
내가 만든 개발보드에서 UART를 통해 전송하는 데이터가 마우스 프로토콜이랑 비슷하게 생겼나?
보드를 USB에 연결하면 마우스가 제멋대로 클릭 되고 움직이고 미쳐버리는 현상이 발생했다.
Baudrate 를 115200 으로 했을때는 이런 현상이 없었는데 2400으로 낮춰놓으니깐 자꾸 마우스를 먹어버리는 것 같아서 baudrate를 39400으로 해놓았더니 그런 현상이 일어나지 않았다.
구글에서 마우스 프로토콜을 찾아보려고 했으나 대충 검색해서 그랬는지 몰라도 찾지 못했다.
내가 만든 개발보드에서 UART를 통해 전송하는 데이터가 마우스 프로토콜이랑 비슷하게 생겼나?
보드를 USB에 연결하면 마우스가 제멋대로 클릭 되고 움직이고 미쳐버리는 현상이 발생했다.
Baudrate 를 115200 으로 했을때는 이런 현상이 없었는데 2400으로 낮춰놓으니깐 자꾸 마우스를 먹어버리는 것 같아서 baudrate를 39400으로 해놓았더니 그런 현상이 일어나지 않았다.
구글에서 마우스 프로토콜을 찾아보려고 했으나 대충 검색해서 그랬는지 몰라도 찾지 못했다.
반응형
'Embeded' 카테고리의 다른 글
기울기 센서 PC와 연동 (2) | 2009.03.26 |
---|---|
withrobot myaccel 이용한 공굴리기 예제. (0) | 2009.03.09 |
OSC, PLL (4) | 2009.03.06 |
Posted by Real_G