OSG仿真案例(9)——JY61陀螺仪控制飞机姿态

2023-10-27

前言
在调试osg中模型运动姿态时,总觉得直观性不够强。所以有了想买个硬件陀螺仪(当时并不知道这个硬件应该叫什么名字,在淘宝搜索角度传感器的)。
几个驱动
1.CH340驱动
这个驱动在自带资源包里面,但是不可以用,只能自己在网上找,发现是型号不对。(自己芯片是CH340N,但是资源的驱动是CH341)。
2.串口驱动
切记不要自己炫技自己写,真的是得不偿失,最后在官网找到了。

include "Com.h"的内容:

#ifndef __UART_NET_H
#define __UART_NET_H
signed char SendUARTMessageLength(const unsigned long ulChannelNo, const char chrMessage[],const unsigned short usLen);
unsigned short CollectUARTData(const unsigned long ulChannelNo, char chrUARTBufferOutput[]);
signed char OpenCOMDevice(const unsigned long ulPortNo);
signed char SetBaundrate(const unsigned long ulPortNo,const unsigned long ulBaundrate);
signed char OpenCOMDevice(const unsigned long ulPortNo,const unsigned long ulBaundrate);
void CloseCOMDevice(void);
#endif

include "Com.cpp"的内容:

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include "Com.h"

#define     TOTAL_PORT_NUM      65
#define     START_PORT_NUM      0

#define     iBufferSize 250
#define     UARTBufferLength 2000
#undef  SYNCHRONOUS_MODE

static HANDLE        hComDev[TOTAL_PORT_NUM]         ={NULL};
static unsigned long long ulComMask = 0;
static HANDLE        hCOMThread[TOTAL_PORT_NUM]      ={NULL};
static OVERLAPPED    stcWriteStatus[TOTAL_PORT_NUM]  = {0};
static OVERLAPPED    stcReadStatus[TOTAL_PORT_NUM]   = {0};

#ifdef SYNCHRONOUS_MODE
static HANDLE        hReceiveEvent[TOTAL_PORT_NUM]   ={NULL};
#endif

static volatile char chrUARTBuffers[TOTAL_PORT_NUM][UARTBufferLength]={0};
static volatile unsigned long ulUARTBufferStart[TOTAL_PORT_NUM]={0}, ulUARTBufferEnd[UARTBufferLength]={0};

unsigned short CollectUARTData(const unsigned long ulCOMNo,char chrUARTBufferOutput[])
{
    unsigned long ulLength=0;
    unsigned long ulEnd ;
    unsigned long ulStart ;

#ifdef SYNCHRONOUS_MODE
    WaitForSingleObject(hReceiveEvent[ulIndexCorrect],INFINITE);
    ResetEvent(hReceiveEvent[ulIndexCorrect]);
#endif
    ulEnd = ulUARTBufferEnd[ulCOMNo];
    ulStart = ulUARTBufferStart[ulCOMNo];
    if (ulEnd == ulStart)
        return(0);
    if (ulEnd > ulStart)
    {
        memcpy((void*)chrUARTBufferOutput,(void*)(chrUARTBuffers[ulCOMNo]+ulStart),ulEnd-ulStart);
        ulLength = ulEnd-ulStart;
    }
    else
    {
        memcpy((void*)chrUARTBufferOutput,(void*)(chrUARTBuffers[ulCOMNo]+ulStart),UARTBufferLength-ulStart);
        if ( ulEnd != 0 )
        {
            memcpy((void*)(chrUARTBufferOutput+(UARTBufferLength-ulStart)),(void*)chrUARTBuffers[ulCOMNo],ulEnd);
        }
        ulLength = UARTBufferLength+ulEnd-ulStart;
    }
    ulUARTBufferStart[ulCOMNo] = ulEnd;
    return (unsigned short) ulLength;
}

signed char SendUARTMessageLength(const unsigned long ulChannelNo, const char chrSendBuffer[],const unsigned short usLen)
{
    DWORD iR;
    DWORD dwRes;
    DCB dcb;
    char chrDataToSend[1000] = {0};
    memcpy(chrDataToSend,chrSendBuffer,usLen);
    memcpy(&chrDataToSend[usLen],chrSendBuffer,usLen);

    GetCommState(hComDev[ulChannelNo] ,&dcb);
    dcb.fDtrControl = 0;//DTR = 1;发送
    SetCommState(hComDev[ulChannelNo] ,&dcb);

    if ( WriteFile(hComDev[ulChannelNo],chrSendBuffer,usLen,&iR,&(stcWriteStatus[ulChannelNo])) || GetLastError() != ERROR_IO_PENDING  ) 
        return -1;
    dwRes = WaitForSingleObject(stcWriteStatus[ulChannelNo].hEvent,1000);
    Sleep(10);
    dcb.fDtrControl = 1;//DTR = 0;接收
    SetCommState(hComDev[ulChannelNo] ,&dcb);
    Sleep(10);

    if(dwRes != WAIT_OBJECT_0 || ! GetOverlappedResult(hComDev[ulChannelNo], &stcWriteStatus[ulChannelNo], &iR, FALSE))
        return 0;
    return 0;
}

DWORD WINAPI ReceiveCOMData(PVOID pParam)
{
    unsigned long uLen;
    unsigned long ulLen1;
    unsigned long ulLen2;
    DWORD   dwRes;
    COMSTAT Comstat;
    DWORD dwErrorFlags;
    char chrBuffer[iBufferSize]={0};
    unsigned long ulUARTBufferEndTemp=ulUARTBufferEnd[0];

    unsigned long ulComNumber = 0;
    memcpy(&ulComNumber,pParam,4);


    while (1)
    {
        if ( ! ReadFile(hComDev[ulComNumber],chrBuffer,iBufferSize-1,&uLen,&(stcReadStatus[ulComNumber])) )
        {
            dwRes = GetLastError() ;
            if ( dwRes != ERROR_IO_PENDING)
            {
                ClearCommError(hComDev[ulComNumber],&dwErrorFlags,&Comstat);
                continue;
            }

            WaitForSingleObject(stcReadStatus[ulComNumber].hEvent,INFINITE);
            if ( !GetOverlappedResult(hComDev[ulComNumber], &(stcReadStatus[ulComNumber]), &uLen, FALSE))
                continue;
            if(uLen <= 0)
                continue;
            if ( (ulUARTBufferEndTemp + uLen) > UARTBufferLength )
            {
                ulLen1 = UARTBufferLength - ulUARTBufferEndTemp;
                ulLen2 = uLen - ulLen1;
                if (ulLen1 > 0)
                {
                    memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]],(void *)chrBuffer,ulLen1);
                }
                if (ulLen2 > 0)
                {
                    memcpy((void *)&chrUARTBuffers[ulComNumber][0],(void *)(chrBuffer+ulLen1),ulLen2);
                }
                ulUARTBufferEndTemp = ulLen2;
            }
            else
            {
                memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]],(void *)chrBuffer,uLen);
                ulUARTBufferEndTemp+=uLen;  
            }

            if (  ulUARTBufferEndTemp == ulUARTBufferStart[ulComNumber])
            {
                printf("Error!");
            }
            else
            {
                ulUARTBufferEnd[ulComNumber] = ulUARTBufferEndTemp;
            }

#ifdef SYNCHRONOUS_MODE
            SetEvent(hReceiveEvent[ucComNumber]);
#endif
            continue;
        }

        if(uLen <= 0)
            continue;
        if ( (ulUARTBufferEndTemp + uLen) > (UARTBufferLength) )
        {
            ulLen1 = UARTBufferLength - ulUARTBufferEndTemp;
            ulLen2 = uLen - ulLen1;
            if (ulLen1 > 0)
            {
                memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]],(void *)chrBuffer,ulLen1);
            }
            if (ulLen2 > 0)
            {
                memcpy((void *)&chrUARTBuffers[ulComNumber][0],(void *)(chrBuffer+ulLen1),ulLen2);
            }
            ulUARTBufferEndTemp = ulLen2;
        }
        else
        {
            memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]],(void *)chrBuffer,uLen);
            ulUARTBufferEndTemp+=uLen;  
        }

        if (  ulUARTBufferEndTemp== ulUARTBufferStart[ulComNumber])
        {
            printf("Error!");
        }
        else
        {
            ulUARTBufferEnd[ulComNumber] = ulUARTBufferEndTemp;
        }   

#ifdef SYNCHRONOUS_MODE
        SetEvent(hReceiveEvent[ucComNumber]);
#endif

    }
    return 0;
}

signed char OpenCOMDevice(const unsigned long ulPortNo,const unsigned long ulBaundrate)
{
    DWORD dwThreadID,dwThreadParam;
    COMSTAT Comstat;
    DWORD dwErrorFlags;
    DWORD dwRes;
    DCB dcb;
    COMMTIMEOUTS comTimeOut;
    TCHAR PortName[10] = {'\\','\\','.','\\','C','O','M',0,0,0};//"\\\\.\\COM";
    TCHAR chrTemple[5]={0};

    if(ulPortNo >= TOTAL_PORT_NUM)
    {
        printf("\nerror: exceed the max com port num\n");
        return -1;
    }


    _itot(ulPortNo+START_PORT_NUM,chrTemple,10);
    _tcscat(PortName,chrTemple);

    if((hComDev[ulPortNo] = CreateFile(PortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED ,NULL))==INVALID_HANDLE_VALUE)
    {
        dwRes=GetLastError();
        return -1;
    }
    ulComMask |= 1<<ulPortNo;

    SetupComm(hComDev[ulPortNo] ,iBufferSize,iBufferSize);
    GetCommState(hComDev[ulPortNo] ,&dcb);
        dcb.BaudRate = ulBaundrate;
    dcb.fParity = NOPARITY;
    dcb.ByteSize=8;
    dcb.fDtrControl = 1;//DTR = 0;接收
    dcb.fRtsControl = 0;//RTS = 0;接收
    dcb.StopBits=ONESTOPBIT;

    SetCommState(hComDev[ulPortNo] ,&dcb);
    ClearCommError(hComDev[ulPortNo] ,&dwErrorFlags,&Comstat);
    dwRes = GetLastError();

    comTimeOut.ReadIntervalTimeout = 5;             
    comTimeOut.ReadTotalTimeoutMultiplier = 10;     
    comTimeOut.ReadTotalTimeoutConstant = 100;      
    comTimeOut.WriteTotalTimeoutMultiplier = 5;     
    comTimeOut.WriteTotalTimeoutConstant = 5;       
    SetCommTimeouts(hComDev[ulPortNo] ,&comTimeOut);    

    stcWriteStatus[ulPortNo] .hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    stcReadStatus[ulPortNo] .hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    stcReadStatus[ulPortNo].Internal = 0;
    stcReadStatus[ulPortNo].InternalHigh = 0;
    stcReadStatus[ulPortNo].Offset = 0;
    stcReadStatus[ulPortNo].OffsetHigh = 0;
    dwThreadParam = ulPortNo;
    hCOMThread[dwThreadParam] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReceiveCOMData,&dwThreadParam,0,&dwThreadID);
    SetThreadPriority(hCOMThread[ulPortNo],THREAD_PRIORITY_NORMAL);
    Sleep(200);

    return 0;

} 

signed char SetBaundrate(const unsigned long ulPortNo,const unsigned long ulBaundrate)
{

    DCB dcb;    
    GetCommState(hComDev[ulPortNo] ,&dcb);
    dcb.BaudRate = ulBaundrate;
    SetCommState(hComDev[ulPortNo] ,&dcb);
    return 0;

} 
void CloseCOMDevice()
{
    unsigned char i;
    for(i=0 ; i<sizeof(ulComMask)*8 ; i++)
    {
        if((ulComMask & (1<<i))==0)
            continue;
        ulUARTBufferEnd[i] = 0;ulUARTBufferStart[i]=0;
        TerminateThread(hCOMThread[i],0);
        WaitForSingleObject(hCOMThread[i],10000);
        PurgeComm(hComDev[i],PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
        CloseHandle(stcReadStatus[i].hEvent);
        CloseHandle(stcWriteStatus[i].hEvent);
        CloseHandle(hComDev[i]);
    }
    ulComMask = 0;
}

上面两个内容,一个代码也没有修改,尊重原始资料。
3.陀螺仪芯片驱动和数据读取

include "JY901.h"的内容(未做任何修改):

#include "JY901.h"
#include "string.h"

CJY901 ::CJY901 ()
{
}

void CJY901 ::CopeSerialData(char ucData[],unsigned short usLength)
{
    static unsigned char chrTemp[2000];
    static unsigned char ucRxCnt = 0;   
    static unsigned short usRxLength = 0;


    memcpy(chrTemp,ucData,usLength);
    usRxLength += usLength;
    while (usRxLength >= 11)
    {
        if (chrTemp[0] != 0x55)
        {
            usRxLength--;
            memcpy(&chrTemp[0],&chrTemp[1],usRxLength);                        
            continue;
        }
        switch(chrTemp[1])
        {
            case 0x50:  memcpy(&stcTime,&chrTemp[2],8);break;
            case 0x51:  memcpy(&stcAcc,&chrTemp[2],8);break;
            case 0x52:  memcpy(&stcGyro,&chrTemp[2],8);break;
            case 0x53:  memcpy(&stcAngle,&chrTemp[2],8);break;
            case 0x54:  memcpy(&stcMag,&chrTemp[2],8);break;
            case 0x55:  memcpy(&stcDStatus,&chrTemp[2],8);break;
            case 0x56:  memcpy(&stcPress,&chrTemp[2],8);break;
            case 0x57:  memcpy(&stcLonLat,&chrTemp[2],8);break;
            case 0x58:  memcpy(&stcGPSV,&chrTemp[2],8);break;
        }
        usRxLength -= 11;
        memcpy(&chrTemp[0],&chrTemp[11],usRxLength);                     
    }
}
CJY901 JY901 = CJY901();

include "JY901.cpp"的内容(未修改):

#include "JY901.h"
#include "string.h"

CJY901 ::CJY901 ()
{
}

void CJY901 ::CopeSerialData(char ucData[],unsigned short usLength)
{
    static unsigned char chrTemp[2000];
    static unsigned char ucRxCnt = 0;   
    static unsigned short usRxLength = 0;


    memcpy(chrTemp,ucData,usLength);
    usRxLength += usLength;
    while (usRxLength >= 11)
    {
        if (chrTemp[0] != 0x55)
        {
            usRxLength--;
            memcpy(&chrTemp[0],&chrTemp[1],usRxLength);                        
            continue;
        }
        switch(chrTemp[1])
        {
            case 0x50:  memcpy(&stcTime,&chrTemp[2],8);break;
            case 0x51:  memcpy(&stcAcc,&chrTemp[2],8);break;
            case 0x52:  memcpy(&stcGyro,&chrTemp[2],8);break;
            case 0x53:  memcpy(&stcAngle,&chrTemp[2],8);break;
            case 0x54:  memcpy(&stcMag,&chrTemp[2],8);break;
            case 0x55:  memcpy(&stcDStatus,&chrTemp[2],8);break;
            case 0x56:  memcpy(&stcPress,&chrTemp[2],8);break;
            case 0x57:  memcpy(&stcLonLat,&chrTemp[2],8);break;
            case 0x58:  memcpy(&stcGPSV,&chrTemp[2],8);break;
        }
        usRxLength -= 11;
        memcpy(&chrTemp[0],&chrTemp[11],usRxLength);                     
    }
}
CJY901 JY901 = CJY901();

4.使用
用的例子还是上一节的内容,加载一个飞机的模型,在其中写上一个matrixTransform1->addUpdateCallback(new CAutoPlane( osg::Vec3(0.0f, 0.0f, 0.0f),osg::Vec3(0.000010f, 0.0f, 0.0f) ));
的回调函数,在这个 CAutoPlane类中,调用硬件数据,实时对模型的姿态进行刷新。

#include <Windows.h>
#include <iostream>
#include <osgDB/ReadFile>
#include <osgViewer/ViewerEventHandlers>
#include <osgAnimation/BasicAnimationManager>
#include <osgDB/ReadFile>
#include <osgEarthUtil/ExampleResources>
#include <osgEarth/Registry>
#include <osgEarthUtil/Controls>
#include <osgEarthSymbology/Color>
void model()
{
    osg::ref_ptr<osgViewer::Viewer> viewer1 = new osgViewer::Viewer;
    osg::ref_ptr<osg::Group> group1 = new osg::Group;
    osg::ref_ptr<osg::MatrixTransform> matrixTransform1 = new osg::MatrixTransform;

    osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("E.......fbx");
    AnimationManagerFinder animationManagerFinder1;
    group1->accept(animationManagerFinder1);
    if (animationManagerFinder1._am.valid())
    {
        std::string playModeOpt;
        osgAnimation::Animation::PlayMode playMode = osgAnimation::Animation::LOOP;
        if (osgDB::equalCaseInsensitive(playModeOpt, "ONCE"))
        {
            playMode = osgAnimation::Animation::ONCE;
        }
        else if (osgDB::equalCaseInsensitive(playModeOpt, "STAY"))
        {
            playMode = osgAnimation::Animation::STAY;
        }
        else if (osgDB::equalCaseInsensitive(playModeOpt, "LOOP"))
        {
            playMode = osgAnimation::Animation::LOOP;
        }
        else if (osgDB::equalCaseInsensitive(playModeOpt, "PPONG"))
        {
            playMode = osgAnimation::Animation::PPONG;
        }

        for (osgAnimation::AnimationList::const_iterator animIter = animationManagerFinder1._am->getAnimationList().begin();
            animIter != animationManagerFinder1._am->getAnimationList().end();
            ++animIter)
        {
            (*animIter)->setPlayMode(playMode);
        }

    }
    matrixTransform1->setMatrix(osg::Matrix::translate(0.0, 0.0, 0.0));
    matrixTransform1->addChild(node1);
    matrixTransform1->addUpdateCallback(
        new CAutoPlane(
            osg::Vec3(0.0f, 0.0f, 0.0f),
            osg::Vec3(0.000010f, 0.0f, 0.0f)
        ));

    group1->addChild(matrixTransform1);
    viewer1->setSceneData(group1);

    viewer1->setUpViewInWindow(200, 200, 800, 600, 0);
    viewer1->run();
}

回调函数 CAutoPlane:

#include "JY901.h"
#include <windows.h>
#include "Com.h"
class CAutoPlane : public osg::NodeCallback
{
public:
    CAutoPlane(osg::Vec3 start, osg::Vec3 speed)
    {
        m_speed = speed;
        heading = 0.0;
        m_pos = 0.0;
        unsigned short usLength = 0, usCnt = 0;
        unsigned long ulBaund = 9600;
        ulComNo = 4;
        signed char cResult = 1;
        while (cResult != 0)
        {
            cResult = OpenCOMDevice(ulComNo, ulBaund);
        }
        usLength = CollectUARTData(ulComNo, chrBuffer);
        if (usLength>0)
        {
            JY901.CopeSerialData(chrBuffer, usLength);
        }

    }
    ~CAutoPlane() {};
osg::Vec3 outRotate()
    {
        usLength = CollectUARTData(ulComNo, chrBuffer);
        if (usLength>0)
        {
            JY901.CopeSerialData(chrBuffer, usLength);
        }
        Sleep(100);

        if (usCnt++ >= 0)
        {
            usCnt = 0;
            printf("Angle:%.3f %.3f %.3f\r\n", (float)JY901.stcAngle.Angle[0] / 32768 * 180, (float)JY901.stcAngle.Angle[1] / 32768 * 180, (float)JY901.stcAngle.Angle[2] / 32768 * 180);
        }
        return osg::Vec3((float)JY901.stcAngle.Angle[0] / 32768 * 180, (float)JY901.stcAngle.Angle[1] / 32768 * 180, (float)JY901.stcAngle.Angle[2] / 32768 * 180);

    }
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        outRotate();
        osg::MatrixTransform * tx = dynamic_cast <osg::MatrixTransform *> (node);
        if (tx != NULL)
        {
            heading += -osg::PI / 1800.0;
            osg::Matrixd orbitRotation;
            orbitRotation.makeRotate(
                osg::DegreesToRadians(outRotate()[0]), osg::Vec3(0, 1, 0),//roll angle (Y axis)
                osg::DegreesToRadians(outRotate()[1]), osg::Vec3(1, 0, 0),//pitch angle (X axis)
                osg::DegreesToRadians(outRotate()[2]), osg::Vec3(0, 0, 1));                //heading angle (Z axis)

            {
                m_start += m_speed;
                tx->setMatrix(orbitRotation * osg::Matrixd::translate(m_start));//直接赋值式改变位置
            }
        }
        traverse(node, nv);
    }
private:
    osg::Vec3 m_start;  //汽车的起始位置
    osg::Vec3 m_speed;  //汽车的行驶速度
    osg::Matrix tempmat;
    float heading;
    float m_pos;
    unsigned short usLength ;
    unsigned short  usCnt;
    char chrBuffer[2000];
    unsigned long ulComNo ;
};

调用

int main(int argc, char **argv)
{
   model();
}

结果

飞机姿态1
飞机姿态2
飞机姿态3
http://www.bilibili.com/video/BV1Zh411k7Ts?share_medium=android&share_source=copy_link&bbid=XY8DB868C46E6A7B9DCC719BE55B83C665BB6&ts=1611922641741
写在最后
(1)买硬件一定要买大厂家的产品,负责,到时候由于相关资料好和资源太少,你会欲哭无泪的。
本系统硬件资料:
链接:
(2)搜索资料,不要找相关,二值要直奔主题,找给厂家的资料,不要像我一样,从:找串口驱动(百度、谷歌、cscd......)——>从自带程序中将C#代码改造成C++——>找技术手册pdf自己写硬件驱动——>修改C51的代码做移植.......最后发现在管网直接由现成的代码考过了就可以用。
(3)关于osg已经oe的各种环境配置,且等我下回分解!
(4)代码链接:链接: https://pan.baidu.com/s/1yGy91iCshJyQokgT0qDqqQ 提取码: 1avh 复制这段内容后打开百度网盘手机App,操作更方便哦
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OSG仿真案例(9)——JY61陀螺仪控制飞机姿态 的相关文章

  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • Google 云端硬盘身份验证异常 - 需要许可吗? (v2)

    我一直在尝试将 Google Drive v2 添加到我的 Android 应用程序中 但无法获得授权 我收到 UserRecoverableAuthIOException 并显示消息 NeedPermission 我感觉 Google A
  • 我想实现下面的布局,按钮应该在屏幕底部,当惰性列被填充时,按钮不应该出去

    顶部有惰性列 惰性列下方有输入电话号码布局并从电话簿布局添加联系人 我希望当未添加联系人时此布局位于顶部 当我添加大量联系人时输入电话号码并添加电话簿布局中的联系人会随着惰性列滚动并移出屏幕 我不让他们走出屏幕 当接触较多时 它们必须粘在底
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • Android Studio 0.4.3 Eclipse项目没有gradle

    在此版本之前 在 Android Studio 中按原样打开 Eclipse 项目似乎很容易 无需任何转换 我更喜欢 Android Studio 环境 但我正在开发一个使用 eclipse 作为主要 IDE 的项目 我不想只为这个项目下载
  • 错误:在根项目“projectName”中找不到项目“app”

    我有一个在 Eclipse 中开发的旧应用程序 现在尝试将其迁移到 Android Studio 我更新了库并遵循了基本步骤 现在 我收到此错误 Error Project app not found in root project pro
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 如何确定对手机号码的呼叫是本地呼叫还是 STD 或 ISD

    我正在为 Android 开发某种应用程序 但不知道如何获取被叫号码是本地或 STD 的号码的数据 即手机号码检查器等应用程序从哪里获取数据 注意 我说的是手机号码 而不是固定电话 固定电话号码 你得到的数字是字符串类型 因此 您可以获取号
  • 一次显示两条Toast消息?

    我希望在一个位置显示一条 Toast 消息 并在另一位置同时显示另一条 Toast 消息 多个 Toast 消息似乎总是按顺序排队和显示 是否可以同时显示两条消息 是否有一种解决方法至少可以提供这种外观并且不涉及扰乱活动布局 Edit 看来
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 强制 Listview 不重复使用视图(复选框)

    我做了一个定制Listview 没有覆盖getView 方法 Listview 中的每个项目都具有以下布局 联系布局 xml

随机推荐

  • 开山之作,简单说说什么是"集群(Cluster)"

    一 什么是集群 集群 Cluster 是由两台或多台节点机 服务器 构成的一种松散耦合的计算节点集合 为用户提 供网络服务或应用程序 包括数据库 Web服务和文件服务等 的单一客户视图 同时提供接近容错机的故 障恢复能力 集群系统一般通过两
  • AndroidStudio项目打包成library以及jar包、aar包流程

    引言 一般项目做多了后 码农们都会整理出一系列的工具类来 为了方便在后面项目中使用 打包成library或者jar aar包供项目使用是比较好的方式 1 library方式 library方式是比较简单的方式 一般新建完一个项目的时候 点击
  • mysql意向锁的概念和用途

    锁的粒度 A 表锁 Table Lock 对整个表加锁 影响标准的所有记录 通常用在DDL语句中 如DELETE TABLE ALTER TABLE等 B 行锁 Row Lock 对一行记录加锁 只影响一条记录 通常用在DML语句中 如IN
  • Visio如何插入公式、MathTape安装

    遇到的问题 在写论文过程中发现Visio没有插入公式的选项 而从word中复制过来邮无法识别 经过我在一番百度以后解决了这个问题 首先要求我们的电脑上已经装好WPS或者MathType 我的电脑已经装了office 所以不想再装WPS 所以
  • 课程计划、课程标准、教材三者关系

    课程主要表现为课程计划 课程标准 教材 教科书是其主要部分 课程计划 国家教育主管部门制定的 包括课程设置 学科顺序 课时分配 学年编制和学周安排 课程标准 国家根据课程计划纲要的形式编写的有关某门学科的内容及实施 评价的指导行文件 如 高
  • 使用nginx搭建的各种服务

    一 nginx搭建文件服务器 1 安装nginx bin bash 安装nginx的脚本文件 先按照nginx的依赖 yum y install gcc openssl devel pcre devel gt dev null echo n
  • pytorch入门篇2 玩转tensor(查看、提取、变换)

    上一篇博客讲述了如何根据自己的实际需要在pytorch中创建tensor pytorch入门篇1 创建tensor 这一篇主要来探讨关于tensor的基本数据变换 是pytorch处理数据的基本方法 文章目录 1 tensor数据查看与提取
  • CentOS7 Failed to start LSB: Bring up/down解决方法

    关于这个问题 网上的有各种解决方法 1 类似于https blog csdn net qq 21398167 article details 46694179这篇文章中提到的 修改mac地址 大多数都是这样 2 类似于http blog 5
  • 回归分析结果表格怎么填_回归分析表怎么看懂?

    展开全部 我给你解读一份stata的回归表格吧 应该有标准表格的所有内容了 因为你没有给范62616964757a686964616fe4b893e5b19e31333332643336例 不过我们考试基本就是考stata或者eview的输
  • AD7606调试过程与源码

    公司有一个项目用到了AD7606 控制器用的STM32 使用的模式是并行16位模式 程序刷好之后发现读取的AD数据乱码 结果发现是因为AD7606的接地不对 当然这个问题是我师傅找出来的 查找的过程如下 用示波器看了BUSY线 转换线等各种
  • Python的request库应用

    我是精神抖擞王大鹏 不卑不亢 和蔼可亲 计算机硕士 目前小米大数据开发 日常会分享总结一些自己面试实际问题的回答 欢迎一起讨论 公众号 diting dapeng Requests是一常用的http请求库 它使用python语言编写 可以方
  • matlab 批量读取execl(csv)文件

    一直没时间整理自己写的垃圾代码 如今代码乱的一团糟 今天把matlab读取excel文件拿出来 需要根据数据格式稍作修改就可以用 读取核心的语句莫过这两句 dir csvread 文件下载 read csvdata author enjoy
  • NoSQL和关系型数据库的区别和使用场景

    NoSQL和关系型数据区别 文章目录 NoSQL和关系型数据区别 一 关系型数据库遵循ACID规则 1 A Atomicty 原子性 2 C Consistency 一致性 3 I Isolation 独立性 4 D Durability
  • Linux笔记

    命令 提供一定功能的工具 ssh 提供远程登录功能 参数 命令的作用对象 193 3 3 3 远程登录的作用主机 选项 命令作用的方式 p 22 通过22端口登录到主机 电脑 外壳shell 内核 输入输出设备 用户 提供意愿 转化为命令与
  • nestjs:Cannot read property ‘retryAttempts‘ of undefined

    描述 Cannot read property retryAttempts of undefined 解决 检查数据库的配置是否有问题
  • 日期格式化方法

    时间格式化 有时候我们会用到时间的展示 时间的展示种类也是各种各样 对于不用的产品需要不同的样式 这时候就需要我们做一下时间的格式化处理 下面是一种常见的日期显示方式 代码如下 格式化时间 param String date 原始时间格式
  • 23种设计模式(七) —— 手写实现 Builder 模式 (组装复杂实例)

    文章目录 一 Builder 模式 二 示例 2 1 示例实现功能 2 2 具体实现 2 3 运行结果 三 Builder 模式中登场的角色 四 原文链接 Author Gorit Date 2021 10 24 2021年发表博文 22
  • 你还不知道的简历准备及面试技巧

    最近已经不止听到一位朋友吐槽工作不好找了 一波又一波的裁员潮 ChatGPT 等人工智能工具的爆火 1158 万的应届毕业生 都让今年 IT 行业的就业状况雪上加霜 面对愈加激烈的求职竞争 作为程序员 应该掌握哪些面试技巧 本文邀请了 2
  • Internet的路由选择协议(RIP、OSPF)

    有关路由选择协议的几个概念 1 理想的路由算法 路由选择协议的核心就是路由算法 即路由器通过算法来获得路由 一个理想的路由算法应该具有以下的特点 算法必须是正确和完整的 算法在计算上应简单 算法应能适应通信量和网络拓扑的变化 算法应具有稳定
  • OSG仿真案例(9)——JY61陀螺仪控制飞机姿态

    前言 在调试osg中模型运动姿态时 总觉得直观性不够强 所以有了想买个硬件陀螺仪 当时并不知道这个硬件应该叫什么名字 在淘宝搜索角度传感器的 几个驱动 1 CH340驱动 这个驱动在自带资源包里面 但是不可以用 只能自己在网上找 发现是型号